From kamlakant.patel at broadcom.com  Tue Oct  1 03:26:13 2013
From: kamlakant.patel at broadcom.com (Kamlakant Patel)
Date: Tue, 1 Oct 2013 12:56:13 +0530
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <20130925231540.GB21682@kroah.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
 <20130925231540.GB21682@kroah.com>
Message-ID: <20131001072612.GA19332@kpatel.netlogicmircro.com>

On Wed, Sep 25, 2013 at 04:15:40PM -0700, Greg KH wrote:
> On Mon, Sep 02, 2013 at 06:52:16PM +0530, Kamlakant Patel wrote:
> > This patch adds support for Micron SPINAND via MTD.
> > 
> > Signed-off-by: Mona Anonuevo <manonuevo at micron.com>
> > Signed-off-by: Kamlakant Patel <kamlakant.patel at broadcom.com>
> > ---
> > This patch has to be merged via staging tree.
> >   
> > This is a driver from Micron for MT29F1G01ZACH4 SPI based NAND chips. This driver had
> > been posted multiple times to the mtd list.
> > 1. http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
> > 2. http://lists.infradead.org/pipermail/linux-mtd/2010-April/029523.html
> > 3. patchwork.ozlabs.org/patch/258697/
> > This has not been merged into the main kernel yet.
> > 
> > I have cleaned and updated it for current kernel. Since there are many users for
> > this driver, it may be useful to add it to the staging tree, where further fixes and
> > cleanups can be done. Once it reaches to the standard will be moved to the mtd.
> > 
> > This driver has been tested with Micron SPINAND MT29F1G01ZACH4 chip on kernel 3.11 on 
> > the Netlogic XLP platform.
> >  
> > Mona Anonuevo, I have retained your sign-offs from the original patch.
> 
> With this applied, I get the following build error:
> 	../ERROR: "nand_scan" [drivers/staging/mt29f_spinand/mt29f_spinand.ko] undefined!
> 
> Can you please fix this and resend a working version?

Thank you for the review, I will fix the dependency issue and resubmit the
patch.

Thanks,
Kamlakant Patel
> 
> thanks,
> 
> greg k-h
> 



From kamlakant.patel at broadcom.com  Tue Oct  1 05:33:58 2013
From: kamlakant.patel at broadcom.com (Kamlakant Patel)
Date: Tue, 1 Oct 2013 15:03:58 +0530
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
Message-ID: <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>

This patch adds support for Micron SPINAND via MTD.

Signed-off-by: Mona Anonuevo <manonuevo at micron.com>
Signed-off-by: Kamlakant Patel <kamlakant.patel at broadcom.com>
---
This patch has to be merged via staging tree.
  
This is a driver from Micron for MT29F1G01ZACH4 SPI based NAND chips. This driver had
been posted multiple times to the mtd list.
1. http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
2. http://lists.infradead.org/pipermail/linux-mtd/2010-April/029523.html
3. patchwork.ozlabs.org/patch/258697/
This has not been merged into the main kernel yet.

I have cleaned and updated it for current kernel. Since there are many users for
this driver, it may be useful to add it to the staging tree, where further fixes and
cleanups can be done. Once it reaches to the standard will be moved to the mtd.

This driver has been tested with Micron SPINAND MT29F1G01ZACH4 chip on kernel 3.12 on
the Netlogic XLP platforms.
 
Mona Anonuevo, I have retained your sign-offs from the original patch.

v1:
* Added MTD_SPINAND_MT29F and MTD_NAND dependencies to avoid build errors.
* Some more code cleanup.

 drivers/staging/Kconfig                       |   2 +
 drivers/staging/Makefile                      |   1 +
 drivers/staging/mt29f_spinand/Kconfig         |  16 +
 drivers/staging/mt29f_spinand/Makefile        |   1 +
 drivers/staging/mt29f_spinand/TODO            |  13 +
 drivers/staging/mt29f_spinand/mt29f_spinand.c | 962 ++++++++++++++++++++++++++
 drivers/staging/mt29f_spinand/mt29f_spinand.h | 107 +++
 7 files changed, 1102 insertions(+)
 create mode 100644 drivers/staging/mt29f_spinand/Kconfig
 create mode 100644 drivers/staging/mt29f_spinand/Makefile
 create mode 100644 drivers/staging/mt29f_spinand/TODO
 create mode 100644 drivers/staging/mt29f_spinand/mt29f_spinand.c
 create mode 100644 drivers/staging/mt29f_spinand/mt29f_spinand.h

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 3626dbc8..3bfdaa8 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -136,6 +136,8 @@ source "drivers/staging/goldfish/Kconfig"
 
 source "drivers/staging/netlogic/Kconfig"
 
+source "drivers/staging/mt29f_spinand/Kconfig"
+
 source "drivers/staging/dwc2/Kconfig"
 
 source "drivers/staging/lustre/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index d1b4b80..b0d3303 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -66,3 +66,4 @@ obj-$(CONFIG_USB_BTMTK)		+= btmtk_usb/
 obj-$(CONFIG_XILLYBUS)		+= xillybus/
 obj-$(CONFIG_DGNC)			+= dgnc/
 obj-$(CONFIG_DGAP)			+= dgap/
+obj-$(CONFIG_MTD_SPINAND_MT29F)	+= mt29f_spinand/
diff --git a/drivers/staging/mt29f_spinand/Kconfig b/drivers/staging/mt29f_spinand/Kconfig
new file mode 100644
index 0000000..4031748
--- /dev/null
+++ b/drivers/staging/mt29f_spinand/Kconfig
@@ -0,0 +1,16 @@
+config MTD_SPINAND_MT29F
+	tristate "SPINAND Device Support for Micron"
+	depends on MTD_NAND && SPI
+	help
+	  This enables support for accessing Micron SPI NAND flash
+	  devices.
+	  If you have Micron SPI NAND chip say yes.
+
+	  If unsure, say no here.
+
+config MTD_SPINAND_ONDIEECC
+	bool "Use SPINAND internal ECC"
+	depends on MTD_SPINAND_MT29F
+	help
+	  Internel ECC.
+	  Enables Hardware ECC support for Micron SPI NAND.
diff --git a/drivers/staging/mt29f_spinand/Makefile b/drivers/staging/mt29f_spinand/Makefile
new file mode 100644
index 0000000..e47af0f
--- /dev/null
+++ b/drivers/staging/mt29f_spinand/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand.o
diff --git a/drivers/staging/mt29f_spinand/TODO b/drivers/staging/mt29f_spinand/TODO
new file mode 100644
index 0000000..a2209b7
--- /dev/null
+++ b/drivers/staging/mt29f_spinand/TODO
@@ -0,0 +1,13 @@
+TODO:
+	- Tested on XLP platform, needs to be tested on other platforms.
+	- Checkpatch.pl cleanups
+	- Sparce fixes.
+	- Clean up coding style to meet kernel standard.
+
+Please send patches
+To:
+Kamlakant Patel <kamlakant.patel at broadcom.com>
+Cc:
+Greg Kroah-Hartman <gregkh at linuxfoundation.org>
+Mona Anonuevo <manonuevo at micron.com>
+linux-mtd at lists.infradead.org
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
new file mode 100644
index 0000000..8e95a57
--- /dev/null
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -0,0 +1,962 @@
+/*
+ * Copyright (c) 2003-2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, Inc.
+ *
+ * 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/module.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+#include <linux/spi/spi.h>
+
+#include "mt29f_spinand.h"
+
+#define BUFSIZE (10 * 64 * 2048)
+#define CACHE_BUF 2112
+/*
+ * OOB area specification layout:  Total 32 available free bytes.
+ */
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int enable_hw_ecc;
+static int enable_read_hw_ecc;
+
+static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+	struct spinand_info *info = (struct spinand_info *)chip->priv;
+	struct spinand_state *state = (struct spinand_state *)info->priv;
+
+	return state;
+}
+
+static struct nand_ecclayout spinand_oob_64 = {
+	.eccbytes = 24,
+	.eccpos = {
+		1, 2, 3, 4, 5, 6,
+		17, 18, 19, 20, 21, 22,
+		33, 34, 35, 36, 37, 38,
+		49, 50, 51, 52, 53, 54, },
+	.oobavail = 32,
+	.oobfree = {
+		{.offset = 8,
+			.length = 8},
+		{.offset = 24,
+			.length = 8},
+		{.offset = 40,
+			.length = 8},
+		{.offset = 56,
+			.length = 8},
+	}
+};
+#endif
+
+/*
+ * spinand_cmd - to process a command to send to the SPI Nand
+ * Description:
+ *    Set up the command buffer to send to the SPI controller.
+ *    The command buffer has to initialized to 0.
+ */
+
+static int spinand_cmd(struct spi_device *spi, struct spinand_cmd *cmd)
+{
+	struct spi_message message;
+	struct spi_transfer x[4];
+	u8 dummy = 0xff;
+
+	spi_message_init(&message);
+	memset(x, 0, sizeof(x));
+
+	x[0].len = 1;
+	x[0].tx_buf = &cmd->cmd;
+	spi_message_add_tail(&x[0], &message);
+
+	if (cmd->n_addr) {
+		x[1].len = cmd->n_addr;
+		x[1].tx_buf = cmd->addr;
+		spi_message_add_tail(&x[1], &message);
+	}
+
+	if (cmd->n_dummy) {
+		x[2].len = cmd->n_dummy;
+		x[2].tx_buf = &dummy;
+		spi_message_add_tail(&x[2], &message);
+	}
+
+	if (cmd->n_tx) {
+		x[3].len = cmd->n_tx;
+		x[3].tx_buf = cmd->tx_buf;
+		spi_message_add_tail(&x[3], &message);
+	}
+
+	if (cmd->n_rx) {
+		x[3].len = cmd->n_rx;
+		x[3].rx_buf = cmd->rx_buf;
+		spi_message_add_tail(&x[3], &message);
+	}
+
+	return spi_sync(spi, &message);
+}
+
+/*
+ * spinand_read_id- Read SPI Nand ID
+ * Description:
+ *    Read ID: read two ID bytes from the SPI Nand device
+ */
+static int spinand_read_id(struct spi_device *spi_nand, u8 *id)
+{
+	int retval;
+	u8 nand_id[3];
+	struct spinand_cmd cmd = {0};
+
+	cmd.cmd = CMD_READ_ID;
+	cmd.n_rx = 3;
+	cmd.rx_buf = &nand_id[0];
+
+	retval = spinand_cmd(spi_nand, &cmd);
+	if (retval < 0) {
+		dev_err(&spi_nand->dev, "error %d reading id\n", retval);
+		return retval;
+	}
+	id[0] = nand_id[1];
+	id[1] = nand_id[2];
+	return retval;
+}
+
+/*
+ * spinand_read_status- send command 0xf to the SPI Nand status register
+ * Description:
+ *    After read, write, or erase, the Nand device is expected to set the
+ *    busy status.
+ *    This function is to allow reading the status of the command: read,
+ *    write, and erase.
+ *    Once the status turns to be ready, the other status bits also are
+ *    valid status bits.
+ */
+static int spinand_read_status(struct spi_device *spi_nand, uint8_t *status)
+{
+	struct spinand_cmd cmd = {0};
+	int ret;
+
+	cmd.cmd = CMD_READ_REG;
+	cmd.n_addr = 1;
+	cmd.addr[0] = REG_STATUS;
+	cmd.n_rx = 1;
+	cmd.rx_buf = status;
+
+	ret = spinand_cmd(spi_nand, &cmd);
+	if (ret < 0)
+		dev_err(&spi_nand->dev, "err: %d read status register\n", ret);
+
+	return ret;
+}
+
+#define MAX_WAIT_JIFFIES  (40 * HZ)
+static int wait_till_ready(struct spi_device *spi_nand)
+{
+	unsigned long deadline;
+	int retval;
+	u8 stat = 0;
+
+	deadline = jiffies + MAX_WAIT_JIFFIES;
+	do {
+		retval = spinand_read_status(spi_nand, &stat);
+		if (retval < 0)
+			return -1;
+		else if (!(stat & 0x1))
+			break;
+
+		cond_resched();
+	} while (!time_after_eq(jiffies, deadline));
+
+	if ((stat & 0x1) == 0)
+		return 0;
+
+	return -1;
+}
+/**
+ * spinand_get_otp- send command 0xf to read the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_get_otp(struct spi_device *spi_nand, u8 *otp)
+{
+	struct spinand_cmd cmd = {0};
+	int retval;
+
+	cmd.cmd = CMD_READ_REG;
+	cmd.n_addr = 1;
+	cmd.addr[0] = REG_OTP;
+	cmd.n_rx = 1;
+	cmd.rx_buf = otp;
+
+	retval = spinand_cmd(spi_nand, &cmd);
+	if (retval < 0)
+		dev_err(&spi_nand->dev, "error %d get otp\n", retval);
+	return retval;
+}
+
+/**
+ * spinand_set_otp- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_set_otp(struct spi_device *spi_nand, u8 *otp)
+{
+	int retval;
+	struct spinand_cmd cmd = {0};
+
+	cmd.cmd = CMD_WRITE_REG,
+	cmd.n_addr = 1,
+	cmd.addr[0] = REG_OTP,
+	cmd.n_tx = 1,
+	cmd.tx_buf = otp,
+
+	retval = spinand_cmd(spi_nand, &cmd);
+	if (retval < 0)
+		dev_err(&spi_nand->dev, "error %d set otp\n", retval);
+
+	return retval;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+/**
+ * spinand_enable_ecc- send command 0x1f to write the SPI Nand OTP register
+ * Description:
+ *   There is one bit( bit 0x10 ) to set or to clear the internal ECC.
+ *   Enable chip internal ECC, set the bit to 1
+ *   Disable chip internal ECC, clear the bit to 0
+ */
+static int spinand_enable_ecc(struct spi_device *spi_nand)
+{
+	int retval;
+	u8 otp = 0;
+
+	retval = spinand_get_otp(spi_nand, &otp);
+	if (retval < 0)
+		return retval;
+
+	if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+		return 0;
+	} else {
+		otp |= OTP_ECC_MASK;
+		retval = spinand_set_otp(spi_nand, &otp);
+		if (retval < 0)
+			return retval;
+		return spinand_get_otp(spi_nand, &otp);
+	}
+}
+#endif
+
+static int spinand_disable_ecc(struct spi_device *spi_nand)
+{
+	int retval;
+	u8 otp = 0;
+
+	retval = spinand_get_otp(spi_nand, &otp);
+	if (retval < 0)
+		return retval;
+
+	if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) {
+		otp &= ~OTP_ECC_MASK;
+		retval = spinand_set_otp(spi_nand, &otp);
+		if (retval < 0)
+			return retval;
+		return spinand_get_otp(spi_nand, &otp);
+	} else
+		return 0;
+}
+
+/**
+ * spinand_write_enable- send command 0x06 to enable write or erase the
+ * Nand cells
+ * Description:
+ *   Before write and erase the Nand cells, the write enable has to be set.
+ *   After the write or erase, the write enable bit is automatically
+ *   cleared (status register bit 2)
+ *   Set the bit 2 of the status register has the same effect
+ */
+static int spinand_write_enable(struct spi_device *spi_nand)
+{
+	struct spinand_cmd cmd = {0};
+
+	cmd.cmd = CMD_WR_ENABLE;
+	return spinand_cmd(spi_nand, &cmd);
+}
+
+static int spinand_read_page_to_cache(struct spi_device *spi_nand, u16 page_id)
+{
+	struct spinand_cmd cmd = {0};
+	u16 row;
+
+	row = page_id;
+	cmd.cmd = CMD_READ;
+	cmd.n_addr = 3;
+	cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+	cmd.addr[2] = (u8)(row & 0x00ff);
+
+	return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_from_cache- send command 0x03 to read out the data from the
+ * cache register(2112 bytes max)
+ * Description:
+ *   The read can specify 1 to 2112 bytes of data read at the corresponding
+ *   locations.
+ *   No tRd delay.
+ */
+static int spinand_read_from_cache(struct spi_device *spi_nand, u16 page_id,
+		u16 byte_id, u16 len, u8 *rbuf)
+{
+	struct spinand_cmd cmd = {0};
+	u16 column;
+
+	column = byte_id;
+	cmd.cmd = CMD_READ_RDM;
+	cmd.n_addr = 3;
+	cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+	cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+	cmd.addr[1] = (u8)(column & 0x00ff);
+	cmd.addr[2] = (u8)(0xff);
+	cmd.n_dummy = 0;
+	cmd.n_rx = len;
+	cmd.rx_buf = rbuf;
+
+	return spinand_cmd(spi_nand, &cmd);
+}
+
+/*
+ * spinand_read_page-to read a page with:
+ * @page_id: the physical page number
+ * @offset:  the location from 0 to 2111
+ * @len:     number of bytes to read
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The read includes two commands to the Nand: 0x13 and 0x03 commands
+ *   Poll to read status to wait for tRD time.
+ */
+static int spinand_read_page(struct spi_device *spi_nand, u16 page_id,
+		u16 offset, u16 len, u8 *rbuf)
+{
+	int ret;
+	u8 status = 0;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+	if (enable_read_hw_ecc) {
+		if (spinand_enable_ecc(spi_nand) < 0)
+			dev_err(&spi_nand->dev, "enable HW ECC failed!");
+	}
+#endif
+	ret = spinand_read_page_to_cache(spi_nand, page_id);
+	if (ret < 0)
+		return ret;
+
+	if (wait_till_ready(spi_nand))
+		dev_err(&spi_nand->dev, "WAIT timedout!!!\n");
+
+	while (1) {
+		ret = spinand_read_status(spi_nand, &status);
+		if (ret < 0) {
+			dev_err(&spi_nand->dev,
+					"err %d read status register\n", ret);
+			return ret;
+		}
+
+		if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+			if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+				dev_err(&spi_nand->dev, "ecc error, page=%d\n",
+						page_id);
+				return 0;
+			}
+			break;
+		}
+	}
+
+	ret = spinand_read_from_cache(spi_nand, page_id, offset, len, rbuf);
+	if (ret < 0) {
+		dev_err(&spi_nand->dev, "read from cache failed!!\n");
+		return ret;
+	}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+	if (enable_read_hw_ecc) {
+		ret = spinand_disable_ecc(spi_nand);
+		if (ret < 0) {
+			dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+			return ret;
+		}
+		enable_read_hw_ecc = 0;
+	}
+#endif
+	return ret;
+}
+
+/*
+ * spinand_program_data_to_cache--to write a page to cache with:
+ * @byte_id: the location to write to the cache
+ * @len:     number of bytes to write
+ * @rbuf:    read buffer to hold @len bytes
+ *
+ * Description:
+ *   The write command used here is 0x84--indicating that the cache is
+ *   not cleared first.
+ *   Since it is writing the data to cache, there is no tPROG time.
+ */
+static int spinand_program_data_to_cache(struct spi_device *spi_nand,
+		u16 page_id, u16 byte_id, u16 len, u8 *wbuf)
+{
+	struct spinand_cmd cmd = {0};
+	u16 column;
+
+	column = byte_id;
+	cmd.cmd = CMD_PROG_PAGE_CLRCACHE;
+	cmd.n_addr = 2;
+	cmd.addr[0] = (u8)((column & 0xff00) >> 8);
+	cmd.addr[0] |= (u8)(((page_id >> 6) & 0x1) << 4);
+	cmd.addr[1] = (u8)(column & 0x00ff);
+	cmd.n_tx = len;
+	cmd.tx_buf = wbuf;
+
+	return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_execute--to write a page from cache to the Nand array with
+ * @page_id: the physical page location to write the page.
+ *
+ * Description:
+ *   The write command used here is 0x10--indicating the cache is writing to
+ *   the Nand array.
+ *   Need to wait for tPROG time to finish the transaction.
+ */
+static int spinand_program_execute(struct spi_device *spi_nand, u16 page_id)
+{
+	struct spinand_cmd cmd = {0};
+	u16 row;
+
+	row = page_id;
+	cmd.cmd = CMD_PROG_PAGE_EXC;
+	cmd.n_addr = 3;
+	cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+	cmd.addr[2] = (u8)(row & 0x00ff);
+
+	return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_program_page--to write a page with:
+ * @page_id: the physical page location to write the page.
+ * @offset:  the location from the cache starting from 0 to 2111
+ * @len:     the number of bytes to write
+ * @wbuf:    the buffer to hold the number of bytes
+ *
+ * Description:
+ *   The commands used here are 0x06, 0x84, and 0x10--indicating that
+ *   the write enable is first sent, the write cache command, and the
+ *   write execute command.
+ *   Poll to wait for the tPROG time to finish the transaction.
+ */
+static int spinand_program_page(struct spi_device *spi_nand,
+		u16 page_id, u16 offset, u16 len, u8 *buf)
+{
+	int retval;
+	u8 status = 0;
+	uint8_t *wbuf;
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+	unsigned int i, j;
+
+	enable_read_hw_ecc = 0;
+	wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL);
+	spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf);
+
+	for (i = offset, j = 0; i < len; i++, j++)
+		wbuf[i] &= buf[j];
+
+	if (enable_hw_ecc) {
+		retval = spinand_enable_ecc(spi_nand);
+		if (retval < 0) {
+			dev_err(&spi_nand->dev, "enable ecc failed!!\n");
+			return retval;
+		}
+	}
+#else
+	wbuf = buf;
+#endif
+	retval = spinand_write_enable(spi_nand);
+	if (retval < 0) {
+		dev_err(&spi_nand->dev, "write enable failed!!\n");
+		return retval;
+	}
+	if (wait_till_ready(spi_nand))
+		dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+	retval = spinand_program_data_to_cache(spi_nand, page_id,
+			offset, len, wbuf);
+	if (retval < 0)
+		return retval;
+	retval = spinand_program_execute(spi_nand, page_id);
+	if (retval < 0)
+		return retval;
+	while (1) {
+		retval = spinand_read_status(spi_nand, &status);
+		if (retval < 0) {
+			dev_err(&spi_nand->dev,
+					"error %d reading status register\n",
+					retval);
+			return retval;
+		}
+
+		if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+			if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) {
+				dev_err(&spi_nand->dev,
+					"program error, page %d\n", page_id);
+				return -1;
+			} else
+				break;
+		}
+	}
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+	if (enable_hw_ecc) {
+		retval = spinand_disable_ecc(spi_nand);
+		if (retval < 0) {
+			dev_err(&spi_nand->dev, "disable ecc failed!!\n");
+			return retval;
+		}
+		enable_hw_ecc = 0;
+	}
+#endif
+
+	return 0;
+}
+
+/**
+ * spinand_erase_block_erase--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The command used here is 0xd8--indicating an erase command to erase
+ *   one block--64 pages
+ *   Need to wait for tERS.
+ */
+static int spinand_erase_block_erase(struct spi_device *spi_nand, u16 block_id)
+{
+	struct spinand_cmd cmd = {0};
+	u16 row;
+
+	row = block_id;
+	cmd.cmd = CMD_ERASE_BLK;
+	cmd.n_addr = 3;
+	cmd.addr[1] = (u8)((row & 0xff00) >> 8);
+	cmd.addr[2] = (u8)(row & 0x00ff);
+
+	return spinand_cmd(spi_nand, &cmd);
+}
+
+/**
+ * spinand_erase_block--to erase a page with:
+ * @block_id: the physical block location to erase.
+ *
+ * Description:
+ *   The commands used here are 0x06 and 0xd8--indicating an erase
+ *   command to erase one block--64 pages
+ *   It will first to enable the write enable bit (0x06 command),
+ *   and then send the 0xd8 erase command
+ *   Poll to wait for the tERS time to complete the tranaction.
+ */
+static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id)
+{
+	int retval;
+	u8 status = 0;
+
+	retval = spinand_write_enable(spi_nand);
+	if (wait_till_ready(spi_nand))
+		dev_err(&spi_nand->dev, "wait timedout!!!\n");
+
+	retval = spinand_erase_block_erase(spi_nand, block_id);
+	while (1) {
+		retval = spinand_read_status(spi_nand, &status);
+		if (retval < 0) {
+			dev_err(&spi_nand->dev,
+					"error %d reading status register\n",
+					(int) retval);
+			return retval;
+		}
+
+		if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+			if ((status & STATUS_E_FAIL_MASK) == STATUS_E_FAIL) {
+				dev_err(&spi_nand->dev,
+					"erase error, block %d\n", block_id);
+				return -1;
+			} else
+				break;
+		}
+	}
+	return 0;
+}
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int spinand_write_page_hwecc(struct mtd_info *mtd,
+		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+	const uint8_t *p = buf;
+	int eccsize = chip->ecc.size;
+	int eccsteps = chip->ecc.steps;
+
+	enable_hw_ecc = 1;
+	chip->write_buf(mtd, p, eccsize * eccsteps);
+	return 0;
+}
+
+static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+		uint8_t *buf, int oob_required, int page)
+{
+	u8 retval, status;
+	uint8_t *p = buf;
+	int eccsize = chip->ecc.size;
+	int eccsteps = chip->ecc.steps;
+	struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+	enable_read_hw_ecc = 1;
+
+	chip->read_buf(mtd, p, eccsize * eccsteps);
+	if (oob_required)
+		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	while (1) {
+		retval = spinand_read_status(info->spi, &status);
+		if ((status & STATUS_OIP_MASK) == STATUS_READY) {
+			if ((status & STATUS_ECC_MASK) == STATUS_ECC_ERROR) {
+				pr_info("spinand: ECC error\n");
+				mtd->ecc_stats.failed++;
+			} else if ((status & STATUS_ECC_MASK) ==
+					STATUS_ECC_1BIT_CORRECTED)
+				mtd->ecc_stats.corrected++;
+			break;
+		}
+	}
+	return 0;
+
+}
+#endif
+
+static void spinand_select_chip(struct mtd_info *mtd, int dev)
+{
+}
+
+static uint8_t spinand_read_byte(struct mtd_info *mtd)
+{
+	struct spinand_state *state = mtd_to_state(mtd);
+	u8 data;
+
+	data = state->buf[state->buf_ptr];
+	state->buf_ptr++;
+	return data;
+}
+
+
+static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
+{
+	struct spinand_info *info = (struct spinand_info *)chip->priv;
+
+	unsigned long timeo = jiffies;
+	int retval, state = chip->state;
+	u8 status;
+
+	if (state == FL_ERASING)
+		timeo += (HZ * 400) / 1000;
+	else
+		timeo += (HZ * 20) / 1000;
+
+	while (time_before(jiffies, timeo)) {
+		retval = spinand_read_status(info->spi, &status);
+		if ((status & STATUS_OIP_MASK) == STATUS_READY)
+			return 0;
+
+		cond_resched();
+	}
+	return 0;
+}
+
+static void spinand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+
+	struct spinand_state *state = mtd_to_state(mtd);
+	memcpy(state->buf + state->buf_ptr, buf, len);
+	state->buf_ptr += len;
+}
+
+static void spinand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	struct spinand_state *state = mtd_to_state(mtd);
+	memcpy(buf, state->buf + state->buf_ptr, len);
+	state->buf_ptr += len;
+}
+
+/*
+ * spinand_reset- send RESET command "0xff" to the Nand device.
+ */
+static void spinand_reset(struct spi_device *spi_nand)
+{
+	struct spinand_cmd cmd = {0};
+
+	cmd.cmd = CMD_RESET;
+
+	if (spinand_cmd(spi_nand, &cmd) < 0)
+		pr_info("spinand reset failed!\n");
+
+	/* elapse 1ms before issuing any other command */
+	udelay(1000);
+
+	if (wait_till_ready(spi_nand))
+		dev_err(&spi_nand->dev, "wait timedout!\n");
+}
+
+static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command,
+		int column, int page)
+{
+	struct nand_chip *chip = (struct nand_chip *)mtd->priv;
+	struct spinand_info *info = (struct spinand_info *)chip->priv;
+	struct spinand_state *state = (struct spinand_state *)info->priv;
+
+	switch (command) {
+	/*
+	 * READ0 - read in first  0x800 bytes
+	 */
+	case NAND_CMD_READ1:
+	case NAND_CMD_READ0:
+		state->buf_ptr = 0;
+		spinand_read_page(info->spi, page, 0x0, 0x840, state->buf);
+		break;
+	/* READOOB reads only the OOB because no ECC is performed. */
+	case NAND_CMD_READOOB:
+		state->buf_ptr = 0;
+		spinand_read_page(info->spi, page, 0x800, 0x40, state->buf);
+		break;
+	case NAND_CMD_RNDOUT:
+		state->buf_ptr = column;
+		break;
+	case NAND_CMD_READID:
+		state->buf_ptr = 0;
+		spinand_read_id(info->spi, (u8 *)state->buf);
+		break;
+	case NAND_CMD_PARAM:
+		state->buf_ptr = 0;
+		break;
+	/* ERASE1 stores the block and page address */
+	case NAND_CMD_ERASE1:
+		spinand_erase_block(info->spi, page);
+		break;
+	/* ERASE2 uses the block and page address from ERASE1 */
+	case NAND_CMD_ERASE2:
+		break;
+	/* SEQIN sets up the addr buffer and all registers except the length */
+	case NAND_CMD_SEQIN:
+		state->col = column;
+		state->row = page;
+		state->buf_ptr = 0;
+		break;
+	/* PAGEPROG reuses all of the setup from SEQIN and adds the length */
+	case NAND_CMD_PAGEPROG:
+		spinand_program_page(info->spi, state->row, state->col,
+				state->buf_ptr, state->buf);
+		break;
+	case NAND_CMD_STATUS:
+		spinand_get_otp(info->spi, state->buf);
+		if (!(state->buf[0] & 0x80))
+			state->buf[0] = 0x80;
+		state->buf_ptr = 0;
+		break;
+	/* RESET command */
+	case NAND_CMD_RESET:
+		if (wait_till_ready(info->spi))
+			dev_err(&info->spi->dev, "WAIT timedout!!!\n");
+		/* a minimum of 250us must elapse before issuing RESET cmd*/
+		udelay(250);
+		spinand_reset(info->spi);
+		break;
+	default:
+		dev_err(&mtd->dev, "Unknown CMD: 0x%x\n", command);
+	}
+}
+
+/**
+ * spinand_lock_block- send write register 0x1f command to the Nand device
+ *
+ * Description:
+ *    After power up, all the Nand blocks are locked.  This function allows
+ *    one to unlock the blocks, and so it can be written or erased.
+ */
+static int spinand_lock_block(struct spi_device *spi_nand, u8 lock)
+{
+	struct spinand_cmd cmd = {0};
+	int ret;
+	u8 otp = 0;
+
+	ret = spinand_get_otp(spi_nand, &otp);
+
+	cmd.cmd = CMD_WRITE_REG;
+	cmd.n_addr = 1;
+	cmd.addr[0] = REG_BLOCK_LOCK;
+	cmd.n_tx = 1;
+	cmd.tx_buf = &lock;
+
+	ret = spinand_cmd(spi_nand, &cmd);
+	if (ret < 0)
+		dev_err(&spi_nand->dev, "error %d lock block\n", ret);
+
+	return ret;
+}
+/*
+ * spinand_probe - [spinand Interface]
+ * @spi_nand: registered device driver.
+ *
+ * Description:
+ *   To set up the device driver parameters to make the device available.
+ */
+static int spinand_probe(struct spi_device *spi_nand)
+{
+	struct mtd_info *mtd;
+	struct nand_chip *chip;
+	struct spinand_info *info;
+	struct spinand_state *state;
+	struct mtd_part_parser_data ppdata;
+
+	info  = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info),
+			GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->spi = spi_nand;
+
+	spinand_lock_block(spi_nand, BL_ALL_UNLOCKED);
+
+	state = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_state),
+			GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	info->priv	= state;
+	state->buf_ptr	= 0;
+	state->buf	= devm_kzalloc(&spi_nand->dev, BUFSIZE, GFP_KERNEL);
+	if (!state->buf)
+		return -ENOMEM;
+
+	chip = devm_kzalloc(&spi_nand->dev, sizeof(struct nand_chip),
+			GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+	chip->ecc.mode	= NAND_ECC_HW;
+	chip->ecc.size	= 0x200;
+	chip->ecc.bytes	= 0x6;
+	chip->ecc.steps	= 0x4;
+
+	chip->ecc.strength = 1;
+	chip->ecc.total	= chip->ecc.steps * chip->ecc.bytes;
+	chip->ecc.layout = &spinand_oob_64;
+	chip->ecc.read_page = spinand_read_page_hwecc;
+	chip->ecc.write_page = spinand_write_page_hwecc;
+#else
+	chip->ecc.mode	= NAND_ECC_SOFT;
+	if (spinand_disable_ecc(spi_nand) < 0)
+		pr_info("%s: disable ecc failed!\n", __func__);
+#endif
+
+	chip->priv	= info;
+	chip->read_buf	= spinand_read_buf;
+	chip->write_buf	= spinand_write_buf;
+	chip->read_byte	= spinand_read_byte;
+	chip->cmdfunc	= spinand_cmdfunc;
+	chip->waitfunc	= spinand_wait;
+	chip->options	|= NAND_CACHEPRG;
+	chip->select_chip = spinand_select_chip;
+
+	mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL);
+	if (!mtd)
+		return -ENOMEM;
+
+	dev_set_drvdata(&spi_nand->dev, mtd);
+
+	mtd->priv = chip;
+	mtd->name = dev_name(&spi_nand->dev);
+	mtd->owner = THIS_MODULE;
+	mtd->oobsize = 64;
+
+	if (nand_scan(mtd, 1))
+		return -ENXIO;
+
+	ppdata.of_node = spi_nand->dev.of_node;
+	return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
+}
+
+/*
+ * spinand_remove: Remove the device driver
+ * @spi: the spi device.
+ *
+ * Description:
+ *   To remove the device driver parameters and free up allocated memories.
+ */
+static int spinand_remove(struct spi_device *spi)
+{
+	mtd_device_unregister(dev_get_drvdata(&spi->dev));
+
+	return 0;
+}
+
+static const struct of_device_id spinand_dt[] = {
+	{ .compatible = "spinand,mt29f", },
+};
+
+/*
+ * Device name structure description
+ */
+static struct spi_driver spinand_driver = {
+	.driver = {
+		.name		= "mt29f",
+		.bus		= &spi_bus_type,
+		.owner		= THIS_MODULE,
+		.of_match_table	= spinand_dt,
+	},
+	.probe		= spinand_probe,
+	.remove		= spinand_remove,
+};
+
+/*
+ * Device driver registration
+ */
+static int __init spinand_init(void)
+{
+	return spi_register_driver(&spinand_driver);
+}
+
+/*
+ * unregister Device driver.
+ */
+static void __exit spinand_exit(void)
+{
+	spi_unregister_driver(&spinand_driver);
+}
+module_init(spinand_init);
+module_exit(spinand_exit);
+
+MODULE_DESCRIPTION("SPI NAND driver for Micron");
+MODULE_AUTHOR("Henry Pan <hspan at micron.com>, Kamlakant Patel <kamlakant.patel at broadcom.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.h b/drivers/staging/mt29f_spinand/mt29f_spinand.h
new file mode 100644
index 0000000..7f2c24d
--- /dev/null
+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.h
@@ -0,0 +1,107 @@
+/*-
+ * Copyright 2013 Broadcom Corporation
+ *
+ * Copyright (c) 2009-2010 Micron Technology, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ * Henry Pan <hspan at micron.com>
+ *
+ * based on nand.h
+ */
+#ifndef __LINUX_MTD_SPI_NAND_H
+#define __LINUX_MTD_SPI_NAND_H
+
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/mtd/mtd.h>
+
+/* cmd */
+#define CMD_READ			0x13
+#define CMD_READ_RDM			0x03
+#define CMD_PROG_PAGE_CLRCACHE		0x02
+#define CMD_PROG_PAGE			0x84
+#define CMD_PROG_PAGE_EXC		0x10
+#define CMD_ERASE_BLK			0xd8
+#define CMD_WR_ENABLE			0x06
+#define CMD_WR_DISABLE			0x04
+#define CMD_READ_ID			0x9f
+#define CMD_RESET			0xff
+#define CMD_READ_REG			0x0f
+#define CMD_WRITE_REG			0x1f
+
+/* feature/ status reg */
+#define REG_BLOCK_LOCK			0xa0
+#define REG_OTP				0xb0
+#define REG_STATUS			0xc0/* timing */
+
+/* status */
+#define STATUS_OIP_MASK			0x01
+#define STATUS_READY			(0 << 0)
+#define STATUS_BUSY			(1 << 0)
+
+#define STATUS_E_FAIL_MASK		0x04
+#define STATUS_E_FAIL			(1 << 2)
+
+#define STATUS_P_FAIL_MASK		0x08
+#define STATUS_P_FAIL			(1 << 3)
+
+#define STATUS_ECC_MASK			0x30
+#define STATUS_ECC_1BIT_CORRECTED	(1 << 4)
+#define STATUS_ECC_ERROR		(2 << 4)
+#define STATUS_ECC_RESERVED		(3 << 4)
+
+/*ECC enable defines*/
+#define OTP_ECC_MASK			0x10
+#define OTP_ECC_OFF			0
+#define OTP_ECC_ON			1
+
+#define ECC_DISABLED
+#define ECC_IN_NAND
+#define ECC_SOFT
+
+/* block lock */
+#define BL_ALL_LOCKED      0x38
+#define BL_1_2_LOCKED      0x30
+#define BL_1_4_LOCKED      0x28
+#define BL_1_8_LOCKED      0x20
+#define BL_1_16_LOCKED     0x18
+#define BL_1_32_LOCKED     0x10
+#define BL_1_64_LOCKED     0x08
+#define BL_ALL_UNLOCKED    0
+
+struct spinand_info {
+	struct nand_ecclayout *ecclayout;
+	struct spi_device *spi;
+	void *priv;
+};
+
+struct spinand_state {
+	uint32_t	col;
+	uint32_t	row;
+	int		buf_ptr;
+	u8		*buf;
+};
+
+struct spinand_cmd {
+	u8		cmd;
+	u32		n_addr;		/* Number of address */
+	u8		addr[3];	/* Reg Offset */
+	u32		n_dummy;	/* Dummy use */
+	u32		n_tx;		/* Number of tx bytes */
+	u8		*tx_buf;	/* Tx buf */
+	u32		n_rx;		/* Number of rx bytes */
+	u8		*rx_buf;	/* Rx buf */
+};
+
+extern int spinand_mtd(struct mtd_info *mtd);
+extern void spinand_mtd_release(struct mtd_info *mtd);
+
+#endif /* __LINUX_MTD_SPI_NAND_H */
-- 
1.8.1.3




From apenwarr at gmail.com  Tue Oct  1 19:01:45 2013
From: apenwarr at gmail.com (Avery Pennarun)
Date: Tue, 1 Oct 2013 16:01:45 -0700
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
Message-ID: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>

Hi everyone,

Does this sound familiar?

Setup:
- Linux 2.6.37 or 3.2.26 (apologies for the old versions, but I
couldn't find any related patches in newer kernels and these are
embedded systems that are a bit hard to upgrade)
- Micron MT29F16G08CBACAWP - MLC NAND
- 1 Mbyte eraseblocks
- 1 kbyte pages
- Tested on two different hardware platforms (MIPS and ARM devices)

Steps:
- Disable ECC to avoid any confusion (ECC turns out to not affect the
test results, but I wanted to make sure)
- Erase any eraseblock
- Write all-zeroes to page 0x18 of that eraseblock; read it back -> ok
- Write all-zeroes to page 0x12 of that eraseblock; read it back ->
FAIL, all 0xff instead
- Read page 0x18 -> completely random data (about 12% of bits are flipped)

More details:
- It doesn't happen with a related Micron SLC NAND
- If you write the pages in the opposite order there is no problem
- Delays before/after reading and writing, and the sequence of reads,
has no effect
- This turns out to happen for any pair of pages, where pairs are
always exactly 6 pages apart (n and n+6), other than the first and
last 4 pages in each eraseblock, which are paired with different pages
to make the math work out

I've read about the concept of MLC "paired pages" causing corruption
elsewhere, but it supposedly only happens when you get a power
failure.  It's happening for me during normal runtime, which seems
wrong.

Has anyone heard of this?

Thanks,

Avery


From ricard.wanderlof at axis.com  Wed Oct  2 03:58:13 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Wed, 2 Oct 2013 09:58:13 +0200
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1310020954040.18310@lnxricardw.se.axis.com>


On Wed, 2 Oct 2013, Avery Pennarun wrote:

> Does this sound familiar?
>
> Setup:
> - Linux 2.6.37 or 3.2.26 (apologies for the old versions, but I
> couldn't find any related patches in newer kernels and these are
> embedded systems that are a bit hard to upgrade)
> - Micron MT29F16G08CBACAWP - MLC NAND
> - 1 Mbyte eraseblocks
> - 1 kbyte pages
> - Tested on two different hardware platforms (MIPS and ARM devices)
>
> Steps:
> - Disable ECC to avoid any confusion (ECC turns out to not affect the
> test results, but I wanted to make sure)
> - Erase any eraseblock
> - Write all-zeroes to page 0x18 of that eraseblock; read it back -> ok
> - Write all-zeroes to page 0x12 of that eraseblock; read it back ->
> FAIL, all 0xff instead
> - Read page 0x18 -> completely random data (about 12% of bits are flipped)
>
> More details:
> - It doesn't happen with a related Micron SLC NAND
> - If you write the pages in the opposite order there is no problem
> - Delays before/after reading and writing, and the sequence of reads,
> has no effect
> - This turns out to happen for any pair of pages, where pairs are
> always exactly 6 pages apart (n and n+6), other than the first and
> last 4 pages in each eraseblock, which are paired with different pages
> to make the math work out
>
> I've read about the concept of MLC "paired pages" causing corruption
> elsewhere, but it supposedly only happens when you get a power
> failure.  It's happening for me during normal runtime, which seems
> wrong.

Not much help, but AFAIU, you can get so-called 'write disturb' when 
writing to the other page in a pair, even without power failure during the 
write. But to my mind, 12% flipped bits sounds very excessive. I don't 
have any experience with MLC though.

Instictively it sounds like there is some other mechanism causing 
problems, for instance if mtd does the write to the pages in two goes, 
rather than in one write, as I think MLC in general can only accept one 
write operation per page, in contrast to SLC where it is legal to write 
the main and oob data at different times (normally 2 or 3 writes per page 
is legal, after that the page must be erased or the data can not be 
considered stable).

/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 romain.izard.pro at gmail.com  Wed Oct  2 06:18:31 2013
From: romain.izard.pro at gmail.com (Romain Izard)
Date: Wed, 2 Oct 2013 10:18:31 +0000 (UTC)
Subject: Page corruption when writing non-sequential pages in an MLC
 NAND eraseblock
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
Message-ID: <l2grtn$svg$1@ger.gmane.org>

On 2013-10-01, Avery Pennarun <apenwarr at gmail.com> wrote:
> Hi everyone,
>
> Does this sound familiar?
>
> Setup:
> - Linux 2.6.37 or 3.2.26 (apologies for the old versions, but I
> couldn't find any related patches in newer kernels and these are
> embedded systems that are a bit hard to upgrade)
> - Micron MT29F16G08CBACAWP - MLC NAND
> - 1 Mbyte eraseblocks
> - 1 kbyte pages
> - Tested on two different hardware platforms (MIPS and ARM devices)
>
> Steps:
> - Disable ECC to avoid any confusion (ECC turns out to not affect the
> test results, but I wanted to make sure)
> - Erase any eraseblock
> - Write all-zeroes to page 0x18 of that eraseblock; read it back -> ok
> - Write all-zeroes to page 0x12 of that eraseblock; read it back ->
> FAIL, all 0xff instead
> - Read page 0x18 -> completely random data (about 12% of bits are flipped)
>
> More details:
> - It doesn't happen with a related Micron SLC NAND
> - If you write the pages in the opposite order there is no problem
> - Delays before/after reading and writing, and the sequence of reads,
> has no effect
> - This turns out to happen for any pair of pages, where pairs are
> always exactly 6 pages apart (n and n+6), other than the first and
> last 4 pages in each eraseblock, which are paired with different pages
> to make the math work out
>
> I've read about the concept of MLC "paired pages" causing corruption
> elsewhere, but it supposedly only happens when you get a power
> failure.  It's happening for me during normal runtime, which seems
> wrong.

For me you're violating one key MLC assumption: the pages within a block
must be written in a strictly increasing order. It should be written
somewhere in the component's datasheet.

Best regards,
-- 
Romain Izard



From alexander.sverdlin at nsn.com  Wed Oct  2 12:42:29 2013
From: alexander.sverdlin at nsn.com (Alexander Sverdlin)
Date: Wed, 02 Oct 2013 18:42:29 +0200
Subject: [PATCH] mtd: phram: Make phram 64-bit compatible
Message-ID: <524C4CF5.7060601@nsn.com>

mtd: phram: Make phram 64-bit compatible

phram was 32-bit limited by design. Machines are growing up, but phram
module is still useful. Update it. The patch is bigger than minimum,
because simple_strtoul() is obsolete.

Tested on MIPS64 and compile-tested for PPC (32 bit).

Signed-off-by: Alexander Sverdlin <alexander.sverdlin at nsn.com>

---
--- linux.orig/drivers/mtd/devices/phram.c
+++ linux/drivers/mtd/devices/phram.c
@@ -94,7 +94,7 @@ static void unregister_devices(void)
 	}
 }

-static int register_device(char *name, unsigned long start, unsigned long len)
+static int register_device(char *name, phys_addr_t start, size_t len)
 {
 	struct phram_mtd_list *new;
 	int ret = -ENOMEM;
@@ -141,35 +141,35 @@ out0:
 	return ret;
 }

-static int ustrtoul(const char *cp, char **endp, unsigned int base)
+static int parse_num64(uint64_t *num64, char *token)
 {
-	unsigned long result = simple_strtoul(cp, endp, base);
+	size_t len;
+	int shift = 0;
+	int ret;

-	switch (**endp) {
-	case 'G':
-		result *= 1024;
-	case 'M':
-		result *= 1024;
-	case 'k':
-		result *= 1024;
+	len = strlen(token);
 	/* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
-		if ((*endp)[1] == 'i')
-			(*endp) += 2;
+	if (len > 2) {
+		if (token[len - 1] == 'i') {
+			switch (token[len - 2]) {
+			case 'G':
+				shift += 10;
+			case 'M':
+				shift += 10;
+			case 'k':
+				shift += 10;
+				token[len - 2] = 0;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
 	}
-	return result;
-}
-
-static int parse_num32(uint32_t *num32, const char *token)
-{
-	char *endp;
-	unsigned long n;

-	n = ustrtoul(token, &endp, 0);
-	if (*endp)
-		return -EINVAL;
+	ret = kstrtou64(token, 0, num64);
+	*num64 <<= shift;

-	*num32 = n;
-	return 0;
+	return ret;
 }

 static int parse_name(char **pname, const char *token)
@@ -209,19 +209,19 @@ static inline void kill_final_newline(ch
  * This shall contain the module parameter if any. It is of the form:
  * - phram=<device>,<address>,<size> for module case
  * - phram.phram=<device>,<address>,<size> for built-in case
- * We leave 64 bytes for the device name, 12 for the address and 12 for the
+ * We leave 64 bytes for the device name, 20 for the address and 20 for the
  * size.
  * Example: phram.phram=rootfs,0xa0000000,512Mi
  */
-static __initdata char phram_paramline[64+12+12];
+static __initdata char phram_paramline[64 + 20 + 20];

 static int __init phram_setup(const char *val)
 {
-	char buf[64+12+12], *str = buf;
+	char buf[64 + 20 + 20], *str = buf;
 	char *token[3];
 	char *name;
-	uint32_t start;
-	uint32_t len;
+	uint64_t start;
+	uint64_t len;
 	int i, ret;

 	if (strnlen(val, sizeof(buf)) >= sizeof(buf))
@@ -243,13 +243,13 @@ static int __init phram_setup(const char
 	if (ret)
 		return ret;

-	ret = parse_num32(&start, token[1]);
+	ret = parse_num64(&start, token[1]);
 	if (ret) {
 		kfree(name);
 		parse_err("illegal start address\n");
 	}

-	ret = parse_num32(&len, token[2]);
+	ret = parse_num64(&len, token[2]);
 	if (ret) {
 		kfree(name);
 		parse_err("illegal device length\n");
@@ -257,7 +257,7 @@ static int __init phram_setup(const char

 	ret = register_device(name, start, len);
 	if (!ret)
-		pr_info("%s device: %#x at %#x\n", name, len, start);
+		pr_info("%s device: %#llx at %#llx\n", name, len, start);
 	else
 		kfree(name);




From computersforpeace at gmail.com  Wed Oct  2 13:57:04 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 10:57:04 -0700
Subject: JFFS2 SUMMARY prior to Linux 3.9
In-Reply-To: <alpine.DEB.2.00.1309161003150.2394@lnxricardw.se.axis.com>
References: <alpine.DEB.2.00.1309161003150.2394@lnxricardw.se.axis.com>
Message-ID: <CAN8TOE8PLvcK4kuRvbRh32gg0_Y8sbwWjdcWh_xt-tgQcPb85Q@mail.gmail.com>

On Mon, Sep 16, 2013 at 1:04 AM, Ricard Wanderlof
<ricard.wanderlof at axis.com> wrote:
> I've noticed that JFFS2 summary has been relieved of it's EXPERIMENTAL
> status since Linux 3.9 . But was it stable enough before then as well? -
> often the EXPERIMENTAL property lingers on longer that it really needs to.

AFAIK, JFFS2 hasn't changed much for many releases, so its current
status pretty well reflects its status for many previous releases.

Regarding the EXPERIMENTAL status; this was changed without CC'ing the
MTD list (although David was CC'd, it seems) in commit:

commit cf98c5e56807af7c793497bbd0446f71c383ffd5
Author: Kees Cook <keescook at chromium.org>
Date:   Wed Jan 16 18:54:12 2013 -0800

    fs/jffs2: remove depends on CONFIG_EXPERIMENTAL

Judging by the commit description, this change just represents a
change in attitude toward the CONFIG_EXPERIMENTAL Kconfig option
rather than any particular judgment of JFFS2 summary support.

Brian


From computersforpeace at gmail.com  Wed Oct  2 14:03:05 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 11:03:05 -0700
Subject: [PATCH] mtd: plat-ram: Remove casting the return value which
 is a void pointer
In-Reply-To: <005801cead1f$6d0af870$4720e950$%han@samsung.com>
References: <005801cead1f$6d0af870$4720e950$%han@samsung.com>
Message-ID: <20131002180305.GQ23337@ld-irv-0074.broadcom.com>

On Mon, Sep 09, 2013 at 02:42:52PM +0900, Jingoo Han wrote:
> Casting the return value which is a void pointer is redundant.
> The conversion from void pointer to any other pointer type is
> guaranteed by the C programming language.
> 
> Signed-off-by: Jingoo Han <jg1.han at samsung.com>
> ---
>  drivers/mtd/maps/plat-ram.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
> index 6762716..3e35b9a 100644
> --- a/drivers/mtd/maps/plat-ram.c
> +++ b/drivers/mtd/maps/plat-ram.c
> @@ -55,7 +55,7 @@ struct platram_info {
>  
>  static inline struct platram_info *to_platram_info(struct platform_device *dev)
>  {
> -	return (struct platram_info *)platform_get_drvdata(dev);
> +	return platform_get_drvdata(dev);
>  }
>  
>  /* platram_setrw

Pushed to l2-mtd.git. Thanks!

Brian


From apenwarr at gmail.com  Wed Oct  2 14:09:44 2013
From: apenwarr at gmail.com (Avery Pennarun)
Date: Wed, 2 Oct 2013 11:09:44 -0700
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <l2grtn$svg$1@ger.gmane.org>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
 <l2grtn$svg$1@ger.gmane.org>
Message-ID: <CAHqTa-3HxoQJ=wEZ_w8Vcp9VXS12=xNbiJ2v8fSsJbMb9BT_4w@mail.gmail.com>

On Wed, Oct 2, 2013 at 3:18 AM, Romain Izard <romain.izard.pro at gmail.com> wrote:
> On 2013-10-01, Avery Pennarun <apenwarr at gmail.com> wrote:
>> Steps:
>> - Disable ECC to avoid any confusion (ECC turns out to not affect the
>> test results, but I wanted to make sure)
>> - Erase any eraseblock
>> - Write all-zeroes to page 0x18 of that eraseblock; read it back -> ok
>> - Write all-zeroes to page 0x12 of that eraseblock; read it back ->
>> FAIL, all 0xff instead
>> - Read page 0x18 -> completely random data (about 12% of bits are flipped)
>
> For me you're violating one key MLC assumption: the pages within a block
> must be written in a strictly increasing order. It should be written
> somewhere in the component's datasheet.

Hmm.  I haven't heard of this constraint, but it certainly seems to be
happening in this case (although in fact random-access writes *mostly*
work other than this pairing effect, so it seems like they intended it
to work properly).

This makes /dev/mtdblock completely unusable as it reorders writes.
Is /dev/mtdblock known to not work with MLC chips?

Thanks,

Avery


From gregkh at linuxfoundation.org  Wed Oct  2 14:22:27 2013
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 2 Oct 2013 11:22:27 -0700
Subject: JFFS2 SUMMARY prior to Linux 3.9
In-Reply-To: <CAN8TOE8PLvcK4kuRvbRh32gg0_Y8sbwWjdcWh_xt-tgQcPb85Q@mail.gmail.com>
References: <alpine.DEB.2.00.1309161003150.2394@lnxricardw.se.axis.com>
 <CAN8TOE8PLvcK4kuRvbRh32gg0_Y8sbwWjdcWh_xt-tgQcPb85Q@mail.gmail.com>
Message-ID: <20131002182227.GA7065@kroah.com>

On Wed, Oct 02, 2013 at 10:57:04AM -0700, Brian Norris wrote:
> On Mon, Sep 16, 2013 at 1:04 AM, Ricard Wanderlof
> <ricard.wanderlof at axis.com> wrote:
> > I've noticed that JFFS2 summary has been relieved of it's EXPERIMENTAL
> > status since Linux 3.9 . But was it stable enough before then as well? -
> > often the EXPERIMENTAL property lingers on longer that it really needs to.
> 
> AFAIK, JFFS2 hasn't changed much for many releases, so its current
> status pretty well reflects its status for many previous releases.
> 
> Regarding the EXPERIMENTAL status; this was changed without CC'ing the
> MTD list (although David was CC'd, it seems) in commit:
> 
> commit cf98c5e56807af7c793497bbd0446f71c383ffd5
> Author: Kees Cook <keescook at chromium.org>
> Date:   Wed Jan 16 18:54:12 2013 -0800
> 
>     fs/jffs2: remove depends on CONFIG_EXPERIMENTAL
> 
> Judging by the commit description, this change just represents a
> change in attitude toward the CONFIG_EXPERIMENTAL Kconfig option
> rather than any particular judgment of JFFS2 summary support.

CONFIG_EXPERIMENTAL was removed from the entire kernel, as it really
didn't mean anything anymore, and hadn't for _years_.

greg k-h


From keescook at chromium.org  Wed Oct  2 14:31:53 2013
From: keescook at chromium.org (Kees Cook)
Date: Wed, 2 Oct 2013 11:31:53 -0700
Subject: JFFS2 SUMMARY prior to Linux 3.9
In-Reply-To: <CAN8TOE8PLvcK4kuRvbRh32gg0_Y8sbwWjdcWh_xt-tgQcPb85Q@mail.gmail.com>
References: <alpine.DEB.2.00.1309161003150.2394@lnxricardw.se.axis.com>
 <CAN8TOE8PLvcK4kuRvbRh32gg0_Y8sbwWjdcWh_xt-tgQcPb85Q@mail.gmail.com>
Message-ID: <CAGXu5jK_BUqkVijBZ3-bhdYWZNf9dEfbJUWRsTuuoR8LWda0qg@mail.gmail.com>

On Wed, Oct 2, 2013 at 10:57 AM, Brian Norris
<computersforpeace at gmail.com> wrote:
> On Mon, Sep 16, 2013 at 1:04 AM, Ricard Wanderlof
> <ricard.wanderlof at axis.com> wrote:
>> I've noticed that JFFS2 summary has been relieved of it's EXPERIMENTAL
>> status since Linux 3.9 . But was it stable enough before then as well? -
>> often the EXPERIMENTAL property lingers on longer that it really needs to.
>
> AFAIK, JFFS2 hasn't changed much for many releases, so its current
> status pretty well reflects its status for many previous releases.
>
> Regarding the EXPERIMENTAL status; this was changed without CC'ing the
> MTD list (although David was CC'd, it seems) in commit:
>
> commit cf98c5e56807af7c793497bbd0446f71c383ffd5
> Author: Kees Cook <keescook at chromium.org>
> Date:   Wed Jan 16 18:54:12 2013 -0800
>
>     fs/jffs2: remove depends on CONFIG_EXPERIMENTAL
>
> Judging by the commit description, this change just represents a
> change in attitude toward the CONFIG_EXPERIMENTAL Kconfig option
> rather than any particular judgment of JFFS2 summary support.

Correct. CONFIG_EXPERIMENTAL was seen to have no meaning any more in
the face of things like distros always turning it on because they
wanted to enable some specific feature/device that was hiding behind
it.

Details about preferred handling of "unstable" features is documented here:
http://git.kernel.org/linus/5a958db311c416345a61b7bddc62a5c6c7112c7f

-Kees

-- 
Kees Cook
Chrome OS Security


From computersforpeace at gmail.com  Wed Oct  2 14:45:47 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 11:45:47 -0700
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
 <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
Message-ID: <20131002184547.GR23337@ld-irv-0074.broadcom.com>

On Tue, Oct 01, 2013 at 03:03:58PM +0530, Kamlakant Patel wrote:
> This patch adds support for Micron SPINAND via MTD.
> 
> Signed-off-by: Mona Anonuevo <manonuevo at micron.com>
> Signed-off-by: Kamlakant Patel <kamlakant.patel at broadcom.com>
> ---
> This patch has to be merged via staging tree.
>   
> This is a driver from Micron for MT29F1G01ZACH4 SPI based NAND chips. This driver had
> been posted multiple times to the mtd list.
> 1. http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
> 2. http://lists.infradead.org/pipermail/linux-mtd/2010-April/029523.html
> 3. patchwork.ozlabs.org/patch/258697/
> This has not been merged into the main kernel yet.
> 
> I have cleaned and updated it for current kernel. Since there are many users for
> this driver, it may be useful to add it to the staging tree, where further fixes and
> cleanups can be done. Once it reaches to the standard will be moved to the mtd.
> 
> This driver has been tested with Micron SPINAND MT29F1G01ZACH4 chip on kernel 3.12 on
> the Netlogic XLP platforms.
>  
> Mona Anonuevo, I have retained your sign-offs from the original patch.
> 
> v1:
> * Added MTD_SPINAND_MT29F and MTD_NAND dependencies to avoid build errors.
> * Some more code cleanup.
> 
>  drivers/staging/Kconfig                       |   2 +
>  drivers/staging/Makefile                      |   1 +
>  drivers/staging/mt29f_spinand/Kconfig         |  16 +
>  drivers/staging/mt29f_spinand/Makefile        |   1 +
>  drivers/staging/mt29f_spinand/TODO            |  13 +
>  drivers/staging/mt29f_spinand/mt29f_spinand.c | 962 ++++++++++++++++++++++++++
>  drivers/staging/mt29f_spinand/mt29f_spinand.h | 107 +++
>  7 files changed, 1102 insertions(+)
>  create mode 100644 drivers/staging/mt29f_spinand/Kconfig
>  create mode 100644 drivers/staging/mt29f_spinand/Makefile
>  create mode 100644 drivers/staging/mt29f_spinand/TODO
>  create mode 100644 drivers/staging/mt29f_spinand/mt29f_spinand.c
>  create mode 100644 drivers/staging/mt29f_spinand/mt29f_spinand.h

...

> diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c
> new file mode 100644
> index 0000000..8e95a57
> --- /dev/null
> +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
> @@ -0,0 +1,962 @@

...

> +#define MAX_WAIT_JIFFIES  (40 * HZ)
> +static int wait_till_ready(struct spi_device *spi_nand)
> +{
> +	unsigned long deadline;
> +	int retval;
> +	u8 stat = 0;
> +
> +	deadline = jiffies + MAX_WAIT_JIFFIES;
> +	do {
> +		retval = spinand_read_status(spi_nand, &stat);
> +		if (retval < 0)
> +			return -1;

You might want to look at using proper error codes here.

> +		else if (!(stat & 0x1))
> +			break;
> +
> +		cond_resched();
> +	} while (!time_after_eq(jiffies, deadline));
> +
> +	if ((stat & 0x1) == 0)
> +		return 0;
> +
> +	return -1;

Same.

> +}

...

> +static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip)
> +{
> +	struct spinand_info *info = (struct spinand_info *)chip->priv;
> +
> +	unsigned long timeo = jiffies;
> +	int retval, state = chip->state;
> +	u8 status;
> +
> +	if (state == FL_ERASING)
> +		timeo += (HZ * 400) / 1000;
> +	else
> +		timeo += (HZ * 20) / 1000;

msecs_to_jiffies()?

> +
> +	while (time_before(jiffies, timeo)) {
> +		retval = spinand_read_status(info->spi, &status);
> +		if ((status & STATUS_OIP_MASK) == STATUS_READY)
> +			return 0;
> +
> +		cond_resched();
> +	}
> +	return 0;
> +}
> +

You can address these comments in follow up patches after it's included
in staging, though. There's probably more review needed anyway
eventually (I see that no one really has reviewed this on the MTD
mailing list yet).

Brian


From computersforpeace at gmail.com  Wed Oct  2 14:46:09 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 11:46:09 -0700
Subject: [PATCH v2] mtd: m25p80: Add support for ESMT F25L32PA
In-Reply-To: <1378250755-2674-1-git-send-email-fggs@terra.com.br>
References: <n>
 <1378250755-2674-1-git-send-email-fggs@terra.com.br>
Message-ID: <20131002184609.GS23337@ld-irv-0074.broadcom.com>

On Tue, Sep 03, 2013 at 08:25:54PM -0300, Flavio Silveira wrote:
> This flashchip is used in D-Link DIR-610 A1 router board 
> and maybe several others, yet is not kernel upstream.
> 
> So add support for it according to datasheet [0], making it easier
> to support other boards using this flashchip in the future.
> 
> Changelog v2:
>  - Better description
>  - Datasheet link at the bottom, similar to other patches.
> 
> [0] http://www.esmt.com.tw/DB/manager/upload/F25L32PA.pdf 
> 
> Signed-off-by: Flavio Silveira <fggs at terra.com.br>
> ---
>  drivers/mtd/devices/m25p80.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 2f3d2a5..3a3cf2d 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -731,6 +731,9 @@ static const struct spi_device_id m25p_ids[] = {
>  	{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
>  	{ "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
>  
> +	/* ESMT */
> +	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
> +
>  	/* Everspin */
>  	{ "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2) },
>  

Removed the changelog and pushed to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Wed Oct  2 14:51:23 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 11:51:23 -0700
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
Message-ID: <20131002185123.GT23337@ld-irv-0074.broadcom.com>

+ Marek

On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
> Micron N25Q512A is a spi flash memory with following features:
> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
> -Memory is organised as 1024(64KB) main sectors.
> -Each sector is divided into 256 pages.
> -Register set/Opcodes are similar to other N25Q family products.
> 
> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
> ---
>  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 26b14f9..94e3b53 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
>  	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
>  	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
>  	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
> +	{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K) },

This device actually has the same ID as Micron's next line (MT25QL512A).
They have the same geometry, so maybe that's not a problem.

(FWIW, I haven't gotten either flash working here, but I'm suspecting
board problems.)

>  
>  	/* PMC */
>  	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },

I'll give Marek a chance to look at this, then I'll take this into
l2-mtd.git if there are no objections.

Brian


From computersforpeace at gmail.com  Wed Oct  2 14:55:04 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 11:55:04 -0700
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <20131002185123.GT23337@ld-irv-0074.broadcom.com>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
 <20131002185123.GT23337@ld-irv-0074.broadcom.com>
Message-ID: <CAN8TOE8k4LCU-6ensOO5OoNuXE+rVOdVaS5S-Q39DGK4CwmNcA@mail.gmail.com>

 + Marek for real!

On Wed, Oct 2, 2013 at 11:51 AM, Brian Norris
<computersforpeace at gmail.com> wrote:
> + Marek
>
> On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
>> Micron N25Q512A is a spi flash memory with following features:
>> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
>> -Memory is organised as 1024(64KB) main sectors.
>> -Each sector is divided into 256 pages.
>> -Register set/Opcodes are similar to other N25Q family products.
>>
>> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
>> ---
>>  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 26b14f9..94e3b53 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
>> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
>>       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
>>       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
>>       { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
>> +     { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K) },
>
> This device actually has the same ID as Micron's next line (MT25QL512A).
> They have the same geometry, so maybe that's not a problem.
>
> (FWIW, I haven't gotten either flash working here, but I'm suspecting
> board problems.)
>
>>
>>       /* PMC */
>>       { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
>
> I'll give Marek a chance to look at this, then I'll take this into
> l2-mtd.git if there are no objections.
>
> Brian


From apenwarr at gmail.com  Wed Oct  2 15:05:28 2013
From: apenwarr at gmail.com (Avery Pennarun)
Date: Wed, 2 Oct 2013 12:05:28 -0700
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <alpine.DEB.2.00.1310020954040.18310@lnxricardw.se.axis.com>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
 <alpine.DEB.2.00.1310020954040.18310@lnxricardw.se.axis.com>
Message-ID: <CAHqTa-2tS_Kw6973m22KehWWTGReCAzjhw5Mwga6sFsHAaOwYQ@mail.gmail.com>

On Wed, Oct 2, 2013 at 12:58 AM, Ricard Wanderlof
<ricard.wanderlof at axis.com> wrote:
> On Wed, 2 Oct 2013, Avery Pennarun wrote:
>> Steps:
>> - Disable ECC to avoid any confusion (ECC turns out to not affect the
>> test results, but I wanted to make sure)
>> - Erase any eraseblock
>> - Write all-zeroes to page 0x18 of that eraseblock; read it back -> ok
>> - Write all-zeroes to page 0x12 of that eraseblock; read it back ->
>> FAIL, all 0xff instead
>> - Read page 0x18 -> completely random data (about 12% of bits are flipped)
>
> Not much help, but AFAIU, you can get so-called 'write disturb' when writing
> to the other page in a pair, even without power failure during the write.
> But to my mind, 12% flipped bits sounds very excessive. I don't have any
> experience with MLC though.
>
> Instictively it sounds like there is some other mechanism causing problems,
> for instance if mtd does the write to the pages in two goes, rather than in
> one write, as I think MLC in general can only accept one write operation per
> page, in contrast to SLC where it is legal to write the main and oob data at
> different times (normally 2 or 3 writes per page is legal, after that the
> page must be erased or the data can not be considered stable).

Thanks Ricard.  Based on this suggestion, I added some trace printk's
to the nand driver and did find that it was writing the data, then the
oob, for each page.  So I commented out all the code that writes to
the oob (since I have ECC disabled anyhow for this test).  The traces
now show just two 4096-byte page writes.  But the problem still
occurs.  So I think that rules out this theory, unless I missed some
ways the nand can be written.

Note that I was slightly mistaken earlier: the number of flipped bits
seems to sometimes be 12%, sometimes 25%.  It's a little suspicious
that this is almostly exactly 1/8 and 1/4 respectively.


From computersforpeace at gmail.com  Wed Oct  2 15:59:38 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 12:59:38 -0700
Subject: [PATCH] UBIFS: fix error return code in ubifs_remount_rw() and
 ubifs_fill_super()
In-Reply-To: <CAPgLHd_=Y=YwCWSFjcacJ14yKUidmmJTHnKKibU6haoBUeNacA@mail.gmail.com>
References: <CAPgLHd_=Y=YwCWSFjcacJ14yKUidmmJTHnKKibU6haoBUeNacA@mail.gmail.com>
Message-ID: <CAN8TOE96Ax_gyeG5fXHejHE6gCmxNchioy1BrE8a6B83kK7A8g@mail.gmail.com>

Bump, Artem? I'm cleaning out my old email, and this patch looks
obviously correct.

On Thu, Jun 6, 2013 at 7:17 PM, Wei Yongjun <weiyj.lk at gmail.com> wrote:
> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
>
> Fix to return -ENOMEM in the kmalloc() and d_make_root() error handling
> case instead of 0, as done elsewhere in those functions.
>
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> ---
>  fs/ubifs/super.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
> index f21acf0..673b4bc 100644
> --- a/fs/ubifs/super.c
> +++ b/fs/ubifs/super.c
> @@ -1629,8 +1629,10 @@ static int ubifs_remount_rw(struct ubifs_info *c)
>         }
>
>         c->write_reserve_buf = kmalloc(COMPRESSED_DATA_NODE_BUF_SZ, GFP_KERNEL);
> -       if (!c->write_reserve_buf)
> +       if (!c->write_reserve_buf) {
> +               err = -ENOMEM;
>                 goto out;
> +       }
>
>         err = ubifs_lpt_init(c, 0, 1);
>         if (err)
> @@ -2063,8 +2065,10 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
>         }
>
>         sb->s_root = d_make_root(root);
> -       if (!sb->s_root)
> +       if (!sb->s_root) {
> +               err = -ENOMEM;
>                 goto out_umount;
> +       }
>
>         mutex_unlock(&c->umount_mutex);
>         return 0;
>
>


From marex at denx.de  Wed Oct  2 16:02:19 2013
From: marex at denx.de (Marek Vasut)
Date: Wed, 2 Oct 2013 22:02:19 +0200
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <CAN8TOE8k4LCU-6ensOO5OoNuXE+rVOdVaS5S-Q39DGK4CwmNcA@mail.gmail.com>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
 <20131002185123.GT23337@ld-irv-0074.broadcom.com>
 <CAN8TOE8k4LCU-6ensOO5OoNuXE+rVOdVaS5S-Q39DGK4CwmNcA@mail.gmail.com>
Message-ID: <201310022202.19877.marex@denx.de>

Hi Brian,

>  + Marek for real!
> 
> On Wed, Oct 2, 2013 at 11:51 AM, Brian Norris
> 
> <computersforpeace at gmail.com> wrote:
> > + Marek
> > 
> > On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
> >> Micron N25Q512A is a spi flash memory with following features:
> >> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
> >> -Memory is organised as 1024(64KB) main sectors.
> >> -Each sector is divided into 256 pages.
> >> -Register set/Opcodes are similar to other N25Q family products.
> >> 
> >> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
> >> ---
> >> 
> >>  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 26b14f9..94e3b53 100644
> >> --- a/drivers/mtd/devices/m25p80.c
> >> +++ b/drivers/mtd/devices/m25p80.c
> >> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
> >> 
> >>       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
> >>       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
> >>       { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
> >> 
> >> +     { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K) },

Why does this n25q256a and n25q512a have exactly the same geometry? I mean, 
those chips differ in size, do they not ? ;-)

> > This device actually has the same ID as Micron's next line (MT25QL512A).
> > They have the same geometry, so maybe that's not a problem.
> > 
> > (FWIW, I haven't gotten either flash working here, but I'm suspecting
> > board problems.)
> > 
> >>       /* PMC */
> >>       { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
> > 
> > I'll give Marek a chance to look at this, then I'll take this into
> > l2-mtd.git if there are no objections.

btw. I got me a board with n25q256a. The chip works fine with recent linux 
kernel, so the ST-related 4-byte addressing change works perfectly.

Best regards,
Marek Vasut


From computersforpeace at gmail.com  Wed Oct  2 16:11:33 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 13:11:33 -0700
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <201310022202.19877.marex@denx.de>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
 <20131002185123.GT23337@ld-irv-0074.broadcom.com>
 <CAN8TOE8k4LCU-6ensOO5OoNuXE+rVOdVaS5S-Q39DGK4CwmNcA@mail.gmail.com>
 <201310022202.19877.marex@denx.de>
Message-ID: <CAN8TOE8ii_fbz77M4HJBvyWwPxe+AGOh-sZW=rrwEKfxGhr61g@mail.gmail.com>

On Wed, Oct 2, 2013 at 1:02 PM, Marek Vasut <marex at denx.de> wrote:
> Hi Brian,
>
>>  + Marek for real!
>>
>> On Wed, Oct 2, 2013 at 11:51 AM, Brian Norris
>>
>> <computersforpeace at gmail.com> wrote:
>> > + Marek
>> >
>> > On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
>> >> Micron N25Q512A is a spi flash memory with following features:
>> >> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
>> >> -Memory is organised as 1024(64KB) main sectors.
>> >> -Each sector is divided into 256 pages.
>> >> -Register set/Opcodes are similar to other N25Q family products.
>> >>
>> >> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
>> >> ---
>> >>
>> >>  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 26b14f9..94e3b53 100644
>> >> --- a/drivers/mtd/devices/m25p80.c
>> >> +++ b/drivers/mtd/devices/m25p80.c
>> >> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
>> >>
>> >>       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
>> >>       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
>> >>       { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
>> >>
>> >> +     { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K) },
>
> Why does this n25q256a and n25q512a have exactly the same geometry? I mean,
> those chips differ in size, do they not ? ;-)
>
>> > This device actually has the same ID as Micron's next line (MT25QL512A).
>> > They have the same geometry, so maybe that's not a problem.

I was referring to Micron n25q512a (which this patch mentions) and
Micron's new generation of flash MT25QL512A (not mentioned in the
original code or patch). They are different flash and are named
differently but have the same ID. Perhaps my usage of the word "line"
was confusing.

>> > (FWIW, I haven't gotten either flash working here, but I'm suspecting
>> > board problems.)
>> >
>> >>       /* PMC */
>> >>       { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
>> >
>> > I'll give Marek a chance to look at this, then I'll take this into
>> > l2-mtd.git if there are no objections.
>
> btw. I got me a board with n25q256a. The chip works fine with recent linux
> kernel, so the ST-related 4-byte addressing change works perfectly.

Good to know. Thanks.

Brian


From computersforpeace at gmail.com  Wed Oct  2 16:20:31 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 13:20:31 -0700
Subject: [PATCH 1/1] mtd: diskonchip: Fix incorrect placement of __initdata
In-Reply-To: <1376300447-7126-1-git-send-email-sachin.kamat@linaro.org>
References: <1376300447-7126-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131002202031.GU23337@ld-irv-0074.broadcom.com>

On Mon, Aug 12, 2013 at 03:10:47PM +0530, Sachin Kamat wrote:
> __initdata should be placed between the variable name and equal
> sign for the variable to be placed in the intended section.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
> ---
>  drivers/mtd/nand/diskonchip.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
> index eaa3c29..b68a495 100644
> --- a/drivers/mtd/nand/diskonchip.c
> +++ b/drivers/mtd/nand/diskonchip.c
> @@ -38,7 +38,7 @@
>  #define CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS 0
>  #endif
>  
> -static unsigned long __initdata doc_locations[] = {
> +static unsigned long doc_locations[] __initdata = {
>  #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
>  #ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
>  	0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,

Pushed to l2-mtd.git. If you're really interested in seeing this
changed, there are a few other similar places in drivers/mtd/. Feel free
to send a patch.

Thanks,
Brian


From marex at denx.de  Wed Oct  2 16:55:01 2013
From: marex at denx.de (Marek Vasut)
Date: Wed, 2 Oct 2013 22:55:01 +0200
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <CAN8TOE8ii_fbz77M4HJBvyWwPxe+AGOh-sZW=rrwEKfxGhr61g@mail.gmail.com>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
 <201310022202.19877.marex@denx.de>
 <CAN8TOE8ii_fbz77M4HJBvyWwPxe+AGOh-sZW=rrwEKfxGhr61g@mail.gmail.com>
Message-ID: <201310022255.01344.marex@denx.de>

Dear Brian Norris,

> On Wed, Oct 2, 2013 at 1:02 PM, Marek Vasut <marex at denx.de> wrote:
> > Hi Brian,
> > 
> >>  + Marek for real!
> >> 
> >> On Wed, Oct 2, 2013 at 11:51 AM, Brian Norris
> >> 
> >> <computersforpeace at gmail.com> wrote:
> >> > + Marek
> >> > 
> >> > On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
> >> >> Micron N25Q512A is a spi flash memory with following features:
> >> >> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
> >> >> -Memory is organised as 1024(64KB) main sectors.
> >> >> -Each sector is divided into 256 pages.
> >> >> -Register set/Opcodes are similar to other N25Q family products.
> >> >> 
> >> >> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
> >> >> ---
> >> >> 
> >> >>  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 26b14f9..94e3b53 100644
> >> >> --- a/drivers/mtd/devices/m25p80.c
> >> >> +++ b/drivers/mtd/devices/m25p80.c
> >> >> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
> >> >> 
> >> >>       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
> >> >>       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
> >> >>       { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
> >> >> 
> >> >> +     { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K) },
> > 
> > Why does this n25q256a and n25q512a have exactly the same geometry? I
> > mean, those chips differ in size, do they not ? ;-)
> > 
> >> > This device actually has the same ID as Micron's next line
> >> > (MT25QL512A). They have the same geometry, so maybe that's not a
> >> > problem.
> 
> I was referring to Micron n25q512a (which this patch mentions) and
> Micron's new generation of flash MT25QL512A (not mentioned in the
> original code or patch). They are different flash and are named
> differently but have the same ID. Perhaps my usage of the word "line"
> was confusing.

Yes I know. Still, that n25q512a line being the exact copy of n25q256a doesn't 
seem right.

The new ql512a seems line just a compatible replacement part for older lineup. 
Happens all the time.

Best regards,
Marek Vasut


From computersforpeace at gmail.com  Wed Oct  2 17:01:51 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 14:01:51 -0700
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <201310022255.01344.marex@denx.de>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
 <201310022202.19877.marex@denx.de>
 <CAN8TOE8ii_fbz77M4HJBvyWwPxe+AGOh-sZW=rrwEKfxGhr61g@mail.gmail.com>
 <201310022255.01344.marex@denx.de>
Message-ID: <CAN8TOE9C1EumkFuWSqJD7+LeatsD5fk-mw8BM0ySZG-udcZC6A@mail.gmail.com>

On Wed, Oct 2, 2013 at 1:55 PM, Marek Vasut <marex at denx.de> wrote:
> Dear Brian Norris,
>
>> On Wed, Oct 2, 2013 at 1:02 PM, Marek Vasut <marex at denx.de> wrote:
>> > Hi Brian,
>> >
>> >>  + Marek for real!
>> >>
>> >> On Wed, Oct 2, 2013 at 11:51 AM, Brian Norris
>> >>
>> >> <computersforpeace at gmail.com> wrote:
>> >> > + Marek
>> >> >
>> >> > On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
>> >> >> Micron N25Q512A is a spi flash memory with following features:
>> >> >> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
>> >> >> -Memory is organised as 1024(64KB) main sectors.
>> >> >> -Each sector is divided into 256 pages.
>> >> >> -Register set/Opcodes are similar to other N25Q family products.
>> >> >>
>> >> >> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
>> >> >> ---
>> >> >>
>> >> >>  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 26b14f9..94e3b53 100644
>> >> >> --- a/drivers/mtd/devices/m25p80.c
>> >> >> +++ b/drivers/mtd/devices/m25p80.c
>> >> >> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
>> >> >>
>> >> >>       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
>> >> >>       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
>> >> >>       { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
>> >> >>
>> >> >> +     { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K) },
>> >
>> > Why does this n25q256a and n25q512a have exactly the same geometry? I
>> > mean, those chips differ in size, do they not ? ;-)
>> >
>> >> > This device actually has the same ID as Micron's next line
>> >> > (MT25QL512A). They have the same geometry, so maybe that's not a
>> >> > problem.
>>
>> I was referring to Micron n25q512a (which this patch mentions) and
>> Micron's new generation of flash MT25QL512A (not mentioned in the
>> original code or patch). They are different flash and are named
>> differently but have the same ID. Perhaps my usage of the word "line"
>> was confusing.
>
> Yes I know. Still, that n25q512a line being the exact copy of n25q256a doesn't
> seem right.

Sorry, I didn't check the original patch carefully enough, and I
subsequently misunderstood your question. I believe the patch is
incorrect; it should be 512Mbit (64MByte) which makes it 64KB sector x
1024 number of sectors, not 64KB sector x 512 number of sectors. Good
catch.

Priyanka, can you submit and test a corrected patch?

> The new ql512a seems line just a compatible replacement part for older lineup.
> Happens all the time.

Hmm, OK.

Brian


From computersforpeace at gmail.com  Wed Oct  2 17:14:01 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 14:14:01 -0700
Subject: [PATCH 01/21] mtd: nand: pxa3xx: Allocate data buffer on
 detected flash size
In-Reply-To: <20130930123756.GB2417@localhost>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-2-git-send-email-ezequiel.garcia@free-electrons.com>
 <20130926201032.GL23337@ld-irv-0074.broadcom.com>
 <20130930123756.GB2417@localhost>
Message-ID: <20131002211401.GV23337@ld-irv-0074.broadcom.com>

On Mon, Sep 30, 2013 at 09:37:57AM -0300, Ezequiel Garcia wrote:
> On Thu, Sep 26, 2013 at 01:10:32PM -0700, Brian Norris wrote:
> > On Thu, Sep 19, 2013 at 01:01:25PM -0300, Ezequiel Garcia wrote:
> > > This commit replaces the currently hardcoded buffer size, by a
> > > dynamic detection scheme. First a small 256 bytes buffer is allocated
> > > so the device can be detected (using READID and friends commands).
> > > 
> > > After detection, this buffer is released and a new buffer is allocated
> > > to acommodate the page size plus out-of-band size.
> > > 
> > > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > 
> > This is the patch that breaks Daniel's DMA setup, right? It looks a bit
> > off.
> 
> What do you mean by 'a bit off'?

The existing code allocates data_buff with kmalloc() or
dma_alloc_coherent() depending on ARCH_HAS_DMA, but your patch does the
initial fixed-size allocation only with kmalloc(). It's just what you
and Daniel already identified: that this causes problems for the DMA
case.

> > BTW, there is a similar issue with at least one other driver (denali.c,
> > maybe others) where the driver uses some hard assumptions about the
> > maximum page/OOB sizes (NAND_MAX_PAGESIZE and NAND_MAX_OOBSIZE). This is
> > kind of ugly and not very sustainable/maintainable, since these
> > dimensions keep increasing. I appreciate your effort to avoid simply
> > kludging in a larger MAX_BUFF_SIZE :) I had similar plans for the other
> > drivers, but I don't know if we'll have much testing opportunities for
> > the ancient ones...
> > 
> > Also, it seems like your driver has a few potential leaks right now. If
> > alloc_nand_resource() succeeds but pxa3xx_nand_probe() later fails
> > (e.g., in pxa3xx_nand_scan()), you don't clean up after yourself. You
> > should address this soon, even if not in this patch series.
> > 
> 
> Hm.. are you sure about that? AFAICS, there's no leak at all.

No, I'm not sure :)

> If alloc_nand_resource() succeeds, the only leakable resources allocated
> are the ones allocated at pxa3xx_nand_init_buff() and the NAND base
> stuff.
> 
> If pxa3xx_nand_probe() later fails to complete, it calls pxa3xx_nand_remove()
> in this part:
> 
> 	if (!probe_success) {
> 		pxa3xx_nand_remove(pdev);
> 		return -ENODEV;
> 	}
> 
> Which takes care of cleaning both the buffers and the NAND base stuff.
> 
> Or am I missing something?

Nope, you were correct. I just missed this point when reading.

Brian


From bpringlemeir at nbsps.com  Wed Oct  2 17:32:01 2013
From: bpringlemeir at nbsps.com (Bill Pringlemeir)
Date: Wed, 02 Oct 2013 17:32:01 -0400
Subject: [PATCH 7/7] UBI: Add some asserts to ubi_attach_fastmap()
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-8-git-send-email-richard@nod.at>
 <CACQ1gAiaSeF0EP9KubJ7SRrLFc=gKq+wEHenFFw-BxJoCx203Q@mail.gmail.com>
Message-ID: <874n8zuzou.fsf@nbsps.com>

On 30 Sep 2013, richard.genoud at gmail.com wrote:

> 2013/9/28 Richard Weinberger <richard at nod.at>:
>> Add more paranioa asserts to make it easier to detect
>> implementation errors.
>>
>> Signed-off-by: Richard Weinberger <richard at nod.at>
>
> Tested-by: Richard Genoud <richard.genoud at gmail.com>

As I reported here,

 http://lists.infradead.org/pipermail/linux-mtd/2013-August/048102.html

This patch-set seems to fix the issue I encountered as well.  I
reflashed my saved image with the updated patch set and the file system
successfully mounts.  Although in my case, it was back-ported.

Fwiw,
Bill Pringlemeir.


From computersforpeace at gmail.com  Wed Oct  2 17:56:28 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 14:56:28 -0700
Subject: [PATCH 03/21] mtd: nand: pxa3xx: Use a completion to signal
 device ready
In-Reply-To: <1379606505-2529-4-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-4-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131002215628.GW23337@ld-irv-0074.broadcom.com>

On Thu, Sep 19, 2013 at 01:01:27PM -0300, Ezequiel Garcia wrote:
> Apparently, the expected behavior of the waitfunc() NAND chip call
> is to wait for the device to be READY (this is a standard chip line).
> However, the current implementation does almost nothing, which opens
> a possibility to issue a command to a non-ready device.
> 
> Fix this by adding a new completion to wait for the ready event to arrive.
> 
> Because the "is ready" flag is cleared from the controller status
> register, it's needed to store that state in the driver, and because the
> field is accesed from an interruption, the field needs to be of an
> atomic type.

Does it really need to be an atomic type? AIUI, you can hand off exclusive
control to the hardware when you begin a command. So the rest of the driver would be
inactive when the IRQ handler is setting the ready flag. And similarly,
the hardware should be inactive (i.e., no interrupts) when you are
modifying the ready flag in the driver (i.e., in cmdfunc).

Or perhaps I'm misunderstanding something.

> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/nand/pxa3xx_nand.c | 45 +++++++++++++++++++++++++++++-------------
>  1 file changed, 31 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> index a8d2ea7..fba91c2 100644
> --- a/drivers/mtd/nand/pxa3xx_nand.c
> +++ b/drivers/mtd/nand/pxa3xx_nand.c
> @@ -35,6 +35,7 @@
>  
>  #include <linux/platform_data/mtd-nand-pxa3xx.h>
>  
> +#define NAND_DEV_READY_TIMEOUT  50
>  #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
>  #define NAND_STOP_DELAY		(2 * HZ/50)
>  #define PAGE_CHUNK_SIZE		(2048)
> @@ -167,7 +168,7 @@ struct pxa3xx_nand_info {
>  	struct clk		*clk;
>  	void __iomem		*mmio_base;
>  	unsigned long		mmio_phys;
> -	struct completion	cmd_complete;
> +	struct completion	cmd_complete, dev_ready;

Do you really need two completion structures? Does 'device ready' always
follow 'command complete', so that you can just use 'device ready' all
the time? And if so, does it make sense to just use dev_ready?

>  
>  	unsigned int 		buf_start;
>  	unsigned int		buf_count;

Brian


From computersforpeace at gmail.com  Wed Oct  2 20:02:53 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 17:02:53 -0700
Subject: [PATCH 00/21] Armada 370/XP NAND support
In-Reply-To: <20130930122428.GA2417@localhost>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20130926195615.GK23337@ld-irv-0074.broadcom.com>
 <20130930122428.GA2417@localhost>
Message-ID: <20131003000253.GX23337@ld-irv-0074.broadcom.com>

On Mon, Sep 30, 2013 at 09:24:29AM -0300, Ezequiel Garcia wrote:
> On Thu, Sep 26, 2013 at 12:56:15PM -0700, Brian Norris wrote:
> > On Thu, Sep 19, 2013 at 01:01:24PM -0300, Ezequiel Garcia wrote:
> > > * Page layout
> > > 
> > > The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
> > > larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
> > > chunked transfers.
> > > 
> > > For instance, if we choose a 2048 data chunk and BCH ECC we will have
> > > to use this layout in the pages:
> > > 
> > >   ------------------------------------------------------------------------------
> > >   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
> > >   ------------------------------------------------------------------------------
> > > 
> > > The last remaining area is unusable (i.e. wasted).
> > 
> > Why is it wasted? With a 2176B buffer, you can fit more than 2048+32+30.
> > Are you simplifying things to support only NAND geometries like the
> > tradiditional large page 2KB+64? (If so, what happens with 4KB pages
> > that need higher level of ECC than can fit in 64 x 2 = 128B?) And in the
> > 2KB+64 case, why is the 64-32-30=2B wasted?
> > 
> 
> Hm... the wasted bytes are due to an 8-byte alignment controller requirement on the
> data buffer. However, you're right: in a flash with a page of 4KB+224B (e.g.) you
> should be able to access at least some of the remaining OOB area.

Alignment requirement for the start of the buffer, length of the buffer,
or both?

> Notice OOB handling is still a bit confusing in this driver.

Yes.

> > > To match this, my current (already working!) implementation acts like
> > > a layout "impedance matcher" to produce in an internal driver's buffer
> > 
> > Maybe I'm in the wrong field, but I'm not sure how an impedance matcher
> > applies here.
> > 
> > > this layout:
> > > 
> > >   ------------------------------------------
> > >   |     4096B data     |     64B spare     |
> > >   ------------------------------------------
> > 
> > What is this "internal buffer"? (I'll read through your patches in a bit
> > and find out, perhaps?) Just the raw data + spare that you are ready to
> > read/write? Are you dropping the ECC from this buffer? Doesn't it need
> > to be returned to the callee (when the 'oob_required' flag is true)?
> > 
> 
> Yes, the driver's internal buffer has the raw data + OOB that has
> been read from the controller after a read operation, or that's
> ready to be written to the flash before a program operation.
> 
> That said, if the command issued was READOOB then the OOB is read fully:
> spare and ECC code and the buffer is filled like this:
> 
>   ----------------------------------------------------------------------------------------------
>   |     4096B data     |  32B spare  |  30B ECC*  | 2x 0xff |  32B spare  |  30B ECC  | 2x 0xff |
>   ----------------------------------------------------------------------------------------------
> 
> (*) We need to add two bytes (0xff) to align the 30B ECC read.
> 
> I was expecting to handle the above layout properly using this nand_ecclayout
> structure:
> 
> static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
>         .eccbytes = 64,
>         .eccpos = {
>                 32,  33,  34,  35,  36,  37,  38,  39,
>                 40,  41,  42,  43,  44,  45,  46,  47,
>                 48,  49,  50,  51,  52,  53,  54,  55,
>                 56,  57,  58,  59,  60,  61,  62,  63,
>                 96,  97,  98,  99,  100, 101, 102, 103,
>                 104, 105, 106, 107, 108, 109, 110, 111,
>                 112, 113, 114, 115, 116, 117, 118, 119,
>                 120, 121, 122, 123, 124, 125, 126, 127},
>         /* Bootrom looks in bytes 0 & 5 for bad blocks */
>         .oobfree = { {1, 4}, {6, 26}, { 64, 32} }
> };
> 
> However, I must be doing something wrong since currently the mtd_oobtest fails
> at some point and I need to investigate the issue further.
> 
> > > In order to achieve reading (for instance), we issue several READ0 commands
> > > (with some additional controller-specific magic) and read two chunks of 2080B
> > > (2048 data + 64 spare) each.
> > 
> > The math is a little inconsistent here and elsewhere. Do you mean two
> > chunks of 2080B (2048 data + 32 spare)?
> > 
> 
> Yes. It should be: 2048B data + 32B spare.
> 
> > > The driver accomodates this data to expose the NAND base a contiguous 4160B buffer
> > > (4096 data + 64 spare).
> > 
> > This math matches up right, if it's double the 2KB+32 instead of double
> > 2KB+64.
> > 
> 
> Yup.
> 
> > > * ECC
> > > 
> > > The controller has built-in hardware ECC capabilities. In addition it is completely
> > > configurable, and we can choose between Hamming and BCH ECC. If we choose BCH ECC
> > > then the ECC code will be calculated for each transfered chunk and expected to be
> > > located (when reading/programming) at specific locations.
> > 
> > At "specific locations", but always within the 30B region that you've
> > been mapping out?
> > 
> 
> By 'specific location' I mean after the 32B spare area.
> 
> > > So, repeating the above scheme, a 2048B data chunk will be followed by 32B spare,
> > > and then the ECC controller will read/write the ECC code (30B in this case):
> > > 
> > >   ------------------------------------
> > >   | 2048B data | 32B spare | 30B ECC |
> > >   ------------------------------------
> > 
> > Is ECC always 30B? Or is this just the maximum size, so you always
> > reserve 30B?
> > 
> 
> In the BCH case, yes: it's always 30B.

So by "BCH" you actually are referring to BCH-4? Are there any other BCH
modes supported? Or do you expect any future revisions to expand on the
BCH options available?

> AFAIK, the ECC works like this. When programming a page, you can
> actually instruct the controller to transfer an arbitrary amount of bytes.
> 
> (Details: you do this by adding NDCB0_LEN_OVRD to the command buffer 0,
> and setting the i/o length at buffer 3).
> 
> The ECC code will be written after the transfered bytes. So, when
> programming a page we configure the length to be 2048B + 32B and get
> the ECC after it.
> 
> Equally, we can read an arbitrary length. and the ECC code is expected
> to be in the area immediate the read area.
> 
> Notice that this means you can control the ECC strength: since the ECC
> is always 30B, and it's calculated on the transfered chunk you can
> configure the controller to transfer the page in 1024B chunks and get a
> 30B ECC for each of this chunk, thus doubling the ECC strength.

This is a little odd. Your ECC HW is not parameterized by ECC strength,
but instead by ECC sector size? I think I have some comments for patch
5, relevant to this topic.

> This should be added to the driver, and I expect it to be fairly easy
> with the infrastructure already in place.

Brian


From computersforpeace at gmail.com  Wed Oct  2 20:24:40 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 17:24:40 -0700
Subject: [PATCH 05/21] mtd: nand: pxa3xx: Add driver-specific ECC BCH
 support
In-Reply-To: <1379606505-2529-6-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-6-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131003002440.GY23337@ld-irv-0074.broadcom.com>

On Thu, Sep 19, 2013 at 01:01:29PM -0300, Ezequiel Garcia wrote:
> This commit adds the BCH ECC support available in NFCv2 controller.
> Depending on the detected required strength the respective ECC layout
> is selected.
> 
> This commit adds an empty ECC layout, since support to access large
> pages is first required. Once that support is added, a proper ECC
> layout will be added as well.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/nand/pxa3xx_nand.c | 53 ++++++++++++++++++++++++++++++++++++------
>  1 file changed, 46 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> index a0dabe6..86c343e 100644
> --- a/drivers/mtd/nand/pxa3xx_nand.c
> +++ b/drivers/mtd/nand/pxa3xx_nand.c

...

> @@ -1117,10 +1133,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
>  	pxa3xx_flash_ids[1].name = NULL;
>  	def = pxa3xx_flash_ids;
>  KEEP_CONFIG:
> -	chip->ecc.mode = NAND_ECC_HW;
> -	chip->ecc.size = host->page_size;
> -	chip->ecc.strength = 1;
> -
>  	if (info->reg_ndcr & NDCR_DWIDTH_M)
>  		chip->options |= NAND_BUSWIDTH_16;
>  
> @@ -1130,8 +1142,35 @@ KEEP_CONFIG:
>  		chip->bbt_options |= NAND_BBT_USE_FLASH;
>  	}
>  
> +	/* Device detection must be done with ECC disabled */
> +	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
> +		nand_writel(info, NDECCCTRL, 0x0);
> +
>  	if (nand_scan_ident(mtd, 1, def))
>  		return -ENODEV;
> +
> +	/* 1-step ECC over the entire detected page size */
> +	chip->ecc.mode = NAND_ECC_HW;
> +	chip->ecc.size = mtd->writesize;

Does the ECC really only work in one step? IOW, do you only correct
1-bit for the entire page? That is under-spec'd for most NAND (they need
1-bit/512-byte, or 4-bit/512-byte). This ecc.size should actually
reflect the correction region (typically 512B or 1024B), and even if
your buffer layout makes a step every 2KB (or 4KB or whatever), the ECC
step size *should* be smaller than that.

Or maybe I'm wrong, and you're actually using a weak 4-bit correction
over 2048 bytes.

> +
> +	/*
> +	 * Armada370 variant supports BCH, which provides 4-bit strength
> +	 * and needs to be supported in a special way.
> +	 */
> +	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&

Might there be other variants eventually that support BCH? Perhaps you
want to separate the property of "can use BCH" from "will use BCH"?

> +	    chip->ecc_strength_ds == 4) {

Do you use BCH-4 only for chips that require exactly 4-bit correction?
Is there ever a need to "overclock" the ECC, and choose BCH-4 for chips
that only require 1-bit correction? Can the bootloader ever make a
choice different from yours here?

What about NAND that don't support the ecc_strength_ds field yet?
Remember, this is only filled for ONFI NAND and a few NAND that are in
the full-ID table.

> +	        chip->ecc.layout = &ecc_layout_4KB_bch4bit;

This seems to have an implicit page size assumption. In your case, it
seems like this layout should be chosen based on the page size + OOB
size, at least.

> +		chip->ecc.strength = chip->ecc_strength_ds;
> +		info->ecc_bch = 1;
> +	} else if (mtd->writesize <= 2048) {
> +		/*
> +		 * This is the default ECC Hamming 1-bit strength case,
> +		 * which works for page sizes of 512 and 2048 bytes.
> +		 * The ECC layout will be automatically configured.
> +		 */
> +		chip->ecc.strength = 1;
> +	}

What about the 'else' case? What happens with >2KB page NAND on
non-Armada370 systems? What happens if a NAND needs >4-bit correction?
Perhaps you could include a warning/error? I don't know the flexibility
of NAND types you'll find on an Armada board; maybe they're all
ONFI-compliant?

> +
>  	/* calculate addressing information */
>  	if (mtd->writesize >= 2048)
>  		host->col_addr_cycles = 2;

Brian


From computersforpeace at gmail.com  Thu Oct  3 01:02:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 2 Oct 2013 22:02:54 -0700
Subject: [GIT PULL] ARM: SoC fixes for 3.12-rc
In-Reply-To: <1379632757.12963.4.camel@shinybook.infradead.org>
References: <20130919194752.GA19975@quad.lixom.net>
 <1379626776.753.164.camel@shinybook.infradead.org>
 <CAN8TOE8j=oosn-5hAdqoTPcuW-sGvDAHd_nK6BZfJpxMwwpisQ@mail.gmail.com>
 <1379632757.12963.4.camel@shinybook.infradead.org>
Message-ID: <CAN8TOE-AozeOs3N0q4x-cMbvRnSTcJYCRx83K-56UJth_WGp3A@mail.gmail.com>

(Trimming CC list)

Hi David,

On Thu, Sep 19, 2013 at 4:19 PM, Woodhouse, David
<david.woodhouse at intel.com> wrote:
> On Thu, 2013-09-19 at 15:57 -0700, Brian Norris wrote:
>> Speaking of such process issues: there's an outstanding patch for a
>> (small) memory leak that was introduced in the nand_base.c ONFI code
>> in 3.12-rc1. Can I expect you to attend to these sort of -rcX (where X
>> > 1) issues? Or should I send Linus the patch myself? I don't really
>> want it to wait around until 3.13-rc1 to go to -stable.
>
> I'm aware of it, and will get to it shortly. Was going to round it up
> along with the one that Olof just sent, either some time this week at
> Plumbers or when I get home.

I see that you have queued up some 3.12-rc patches in linux-mtd.git.
This is a reminder to send a pull request...

> If you want to stick it in the linux-mtd.git tree before that and send
> Linus a pull request, I have no objection.

...or else I will just send them myself within a week.

Thanks,
Brian


From gregkh at linuxfoundation.org  Thu Oct  3 01:24:18 2013
From: gregkh at linuxfoundation.org (Greg KH)
Date: Wed, 2 Oct 2013 22:24:18 -0700
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
 <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
Message-ID: <20131003052418.GC1312@kroah.com>

On Tue, Oct 01, 2013 at 03:03:58PM +0530, Kamlakant Patel wrote:
> --- a/drivers/staging/Kconfig
> +++ b/drivers/staging/Kconfig
> @@ -136,6 +136,8 @@ source "drivers/staging/goldfish/Kconfig"
>  
>  source "drivers/staging/netlogic/Kconfig"
>  
> +source "drivers/staging/mt29f_spinand/Kconfig"
> +

Any reason you don't put it at the end of the file, and need it here in
the middle?

thanks,

greg k-h


From gregkh at linuxfoundation.org  Thu Oct  3 01:25:51 2013
From: gregkh at linuxfoundation.org (Greg KH)
Date: Wed, 2 Oct 2013 22:25:51 -0700
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
 <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
Message-ID: <20131003052551.GD1312@kroah.com>

On Tue, Oct 01, 2013 at 03:03:58PM +0530, Kamlakant Patel wrote:
> 
>  drivers/staging/Kconfig                       |   2 +
>  drivers/staging/Makefile                      |   1 +
>  drivers/staging/mt29f_spinand/Kconfig         |  16 +
>  drivers/staging/mt29f_spinand/Makefile        |   1 +
>  drivers/staging/mt29f_spinand/TODO            |  13 +
>  drivers/staging/mt29f_spinand/mt29f_spinand.c | 962 ++++++++++++++++++++++++++
>  drivers/staging/mt29f_spinand/mt29f_spinand.h | 107 +++

Why do you need a separate .h file for a single driver?

It's not a reason to reject this, just curious if it's that way for a
reason.  I'll look at this closer tomorrow and apply it if it passes my
minor amount of build testing.

thanks,

greg k-h


From pekon at ti.com  Thu Oct  3 01:49:58 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 3 Oct 2013 05:49:58 +0000
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <20131002184547.GR23337@ld-irv-0074.broadcom.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
 <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
 <20131002184547.GR23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA19568@DBDE04.ent.ti.com>

> From: linux-mtd  On Behalf Of Brian Norris
> > On Tue, Oct 01, 2013 at 03:03:58PM +0530, Kamlakant Patel wrote:
> > This patch adds support for Micron SPINAND via MTD.
> >
> > Signed-off-by: Mona Anonuevo <manonuevo at micron.com>
> > Signed-off-by: Kamlakant Patel <kamlakant.patel at broadcom.com>
> > ---
> > This patch has to be merged via staging tree.
> >
> > This is a driver from Micron for MT29F1G01ZACH4 SPI based NAND chips.
> This driver had
> > been posted multiple times to the mtd list.
> > 1. http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
> > 2. http://lists.infradead.org/pipermail/linux-mtd/2010-April/029523.html
> > 3. patchwork.ozlabs.org/patch/258697/
> > This has not been merged into the main kernel yet.
> >
> > I have cleaned and updated it for current kernel. Since there are many
> users for
> > this driver, it may be useful to add it to the staging tree, where further fixes
> and
> > cleanups can be done. Once it reaches to the standard will be moved to the
> mtd.
> >
> > This driver has been tested with Micron SPINAND MT29F1G01ZACH4 chip
> on kernel 3.12 on
> > the Netlogic XLP platforms.
> >
> > Mona Anonuevo, I have retained your sign-offs from the original patch.
> >
I see that major portion (especially the generic framework) is ported from
http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
So shouldn't you just maintain the original authorship ?
And the original headers ?

> 
> You can address these comments in follow up patches after it's included
> in staging, though. There's probably more review needed anyway
> eventually (I see that no one really has reviewed this on the MTD
> mailing list yet).
> 
The original version of this patch in 2010 added *generic spinand*
framework. And support for m29f (Micron devices) should have been
added using that generic framework. But due to lack of response
generic framework never went in.
Therefore I think this patch series adds a customized driver just for
'm29f' (Micron serial NAND) devices, removing the generalization.

There was a refreshed version of original patch (with generic framework)
but no response on that too. I don't want to hold this patch, but it would
be good, if you can review generic framework also ..
https://lkml.org/lkml/2013/6/26/88


with regards, pekon


From prabhakar at freescale.com  Thu Oct  3 02:06:41 2013
From: prabhakar at freescale.com (Prabhakar Kushwaha)
Date: Thu, 3 Oct 2013 11:36:41 +0530
Subject: [PATCH] driver/mtd/ifc: Read Status while programming NAND flash
Message-ID: <1380780401-6640-1-git-send-email-prabhakar@freescale.com>

as per controller description,
  "While programming a NAND flash, status read should never skipped.
   Because it may happen that a new command is issued to the NAND Flash,
   even when the device has not yet finished processing the previous request.
   This may result in unpredictable behaviour."

IFC controller never polls for R/B signal after command send. It just return
control to software. This behaviour may not occur with NAND flash access.
because new commands are sent after polling R/B signal. But it may happen
in scenario where GPCM-ASIC and NAND flash device are working simultaneously.

Update the controller driver to take care of this requirement

Signed-off-by: Prabhakar Kushwaha <prabhakar at freescale.com>
---
 drivers/mtd/nand/fsl_ifc_nand.c |   34 ++++++++++++++++++++++++----------
 1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index a14885b..eb150f1 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -504,20 +504,29 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 		if (mtd->writesize > 512) {
 			nand_fcr0 =
 				(NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
-				(NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT);
+				(NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
+				(NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
 
 			iowrite32be(
-				(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
-				(IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
-				(IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
-				(IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) |
-				(IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT),
-				&ifc->ifc_nand.nand_fir0);
+				 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
+				 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
+				 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
+				 (IFC_FIR_OP_WBCD  << IFC_NAND_FIR0_OP3_SHIFT) |
+				 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT),
+				 &ifc->ifc_nand.nand_fir0);
+			iowrite32be(
+				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
+				 (IFC_FIR_OP_RDSTAT <<
+					IFC_NAND_FIR1_OP6_SHIFT) |
+				 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT),
+				 &ifc->ifc_nand.nand_fir1);
 		} else {
 			nand_fcr0 = ((NAND_CMD_PAGEPROG <<
 					IFC_NAND_FCR0_CMD1_SHIFT) |
 				    (NAND_CMD_SEQIN <<
-					IFC_NAND_FCR0_CMD2_SHIFT));
+					IFC_NAND_FCR0_CMD2_SHIFT) |
+				    (NAND_CMD_STATUS <<
+					IFC_NAND_FCR0_CMD3_SHIFT));
 
 			iowrite32be(
 				(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
@@ -526,8 +535,13 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
 				(IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
 				(IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT),
 				&ifc->ifc_nand.nand_fir0);
-			iowrite32be(IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT,
-				    &ifc->ifc_nand.nand_fir1);
+			iowrite32be(
+				 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
+				 (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
+				 (IFC_FIR_OP_RDSTAT <<
+					IFC_NAND_FIR1_OP7_SHIFT) |
+				 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT),
+				  &ifc->ifc_nand.nand_fir1);
 
 			if (column >= mtd->writesize)
 				nand_fcr0 |=
-- 
1.7.9.5





From ricard.wanderlof at axis.com  Thu Oct  3 02:57:01 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Thu, 3 Oct 2013 08:57:01 +0200
Subject: JFFS2 SUMMARY prior to Linux 3.9
In-Reply-To: <CAGXu5jK_BUqkVijBZ3-bhdYWZNf9dEfbJUWRsTuuoR8LWda0qg@mail.gmail.com>
References: <alpine.DEB.2.00.1309161003150.2394@lnxricardw.se.axis.com>
 <CAN8TOE8PLvcK4kuRvbRh32gg0_Y8sbwWjdcWh_xt-tgQcPb85Q@mail.gmail.com>
 <CAGXu5jK_BUqkVijBZ3-bhdYWZNf9dEfbJUWRsTuuoR8LWda0qg@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1310030850020.18310@lnxricardw.se.axis.com>


On Wed, 2 Oct 2013, Kees Cook wrote:

> On Wed, Oct 2, 2013 at 10:57 AM, Brian Norris
> <computersforpeace at gmail.com> wrote:
>> On Mon, Sep 16, 2013 at 1:04 AM, Ricard Wanderlof
>> <ricard.wanderlof at axis.com> wrote:
>>> I've noticed that JFFS2 summary has been relieved of it's EXPERIMENTAL
>>> status since Linux 3.9 . But was it stable enough before then as well? -
>>> often the EXPERIMENTAL property lingers on longer that it really needs to.
>>
>> AFAIK, JFFS2 hasn't changed much for many releases, so its current
>> status pretty well reflects its status for many previous releases.
>>
>> Regarding the EXPERIMENTAL status; this was changed without CC'ing the
>> MTD list (although David was CC'd, it seems) in commit:
>>
>> commit cf98c5e56807af7c793497bbd0446f71c383ffd5
>> Author: Kees Cook <keescook at chromium.org>
>> Date:   Wed Jan 16 18:54:12 2013 -0800
>>
>>     fs/jffs2: remove depends on CONFIG_EXPERIMENTAL
>>
>> Judging by the commit description, this change just represents a
>> change in attitude toward the CONFIG_EXPERIMENTAL Kconfig option
>> rather than any particular judgment of JFFS2 summary support.
>
> Correct. CONFIG_EXPERIMENTAL was seen to have no meaning any more in
> the face of things like distros always turning it on because they
> wanted to enable some specific feature/device that was hiding behind
> it.
>
> Details about preferred handling of "unstable" features is documented here:
> http://git.kernel.org/linus/5a958db311c416345a61b7bddc62a5c6c7112c7f

Thanks for the clarifications and link guys.

It does seem though that if a feature really is 'experimental', it could 
still be marked as "(EXPERIMENTAL)" in Kconfig as well as having 
appropriate warnings in the help text, purely as a warning to users. I 
quite frankly wasn't aware of CONFIG_EXPERIMENTAL (which just cements the 
fact that no one really cared about that option anyway) as I hadn't 
reviewed the Kconfig file, just noticed the "(EXPERIMENTAL)" in the 
resulting menu item.

All the above points to the fact that for this particular option, 
"(EXPERIMENTAL)" was left in mostly because no one had bothered to remove 
it. There doesn't seem to be any other indication in the Kconfig that
the option is in fact unstable.

/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 sachin.kamat at linaro.org  Thu Oct  3 03:02:31 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Thu, 3 Oct 2013 12:32:31 +0530
Subject: [PATCH 1/1] mtd: diskonchip: Fix incorrect placement of __initdata
In-Reply-To: <20131002202031.GU23337@ld-irv-0074.broadcom.com>
References: <1376300447-7126-1-git-send-email-sachin.kamat@linaro.org>
 <20131002202031.GU23337@ld-irv-0074.broadcom.com>
Message-ID: <CAK9yfHwgPE5tOZV53gLk-QKJbKSnuBLKWWMuSzspQXAT9qq_PQ@mail.gmail.com>

On 3 October 2013 01:50, Brian Norris <computersforpeace at gmail.com> wrote:
> On Mon, Aug 12, 2013 at 03:10:47PM +0530, Sachin Kamat wrote:
>> -static unsigned long __initdata doc_locations[] = {
>> +static unsigned long doc_locations[] __initdata = {
>>  #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
>>  #ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
>>       0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
>

> Pushed to l2-mtd.git.

Thanks.

> If you're really interested in seeing this
> changed, there are a few other similar places in drivers/mtd/. Feel free
> to send a patch.
>

Sure. I will take a look at remaining instances and send the necessary patches.
Thanks.

-- 
With warm regards,
Sachin


From ricard.wanderlof at axis.com  Thu Oct  3 03:40:43 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Thu, 3 Oct 2013 09:40:43 +0200
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <CAHqTa-3HxoQJ=wEZ_w8Vcp9VXS12=xNbiJ2v8fSsJbMb9BT_4w@mail.gmail.com>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
 <l2grtn$svg$1@ger.gmane.org>
 <CAHqTa-3HxoQJ=wEZ_w8Vcp9VXS12=xNbiJ2v8fSsJbMb9BT_4w@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1310030932150.18310@lnxricardw.se.axis.com>


On Wed, 2 Oct 2013, Avery Pennarun wrote:

> On Wed, Oct 2, 2013 at 3:18 AM, Romain Izard <romain.izard.pro at gmail.com> wrote:
>> On 2013-10-01, Avery Pennarun <apenwarr at gmail.com> wrote:
>>> Steps:
>>> - Disable ECC to avoid any confusion (ECC turns out to not affect the
>>> test results, but I wanted to make sure)
>>> - Erase any eraseblock
>>> - Write all-zeroes to page 0x18 of that eraseblock; read it back -> ok
>>> - Write all-zeroes to page 0x12 of that eraseblock; read it back ->
>>> FAIL, all 0xff instead
>>> - Read page 0x18 -> completely random data (about 12% of bits are flipped)
>>
>> For me you're violating one key MLC assumption: the pages within a block
>> must be written in a strictly increasing order. It should be written
>> somewhere in the component's datasheet.
>
> Hmm.  I haven't heard of this constraint, but it certainly seems to be
> happening in this case (although in fact random-access writes *mostly*
> work other than this pairing effect, so it seems like they intended it
> to work properly).

Just because they place the constraint on the user that the pages must be 
written in order doesn't mean that the device necessarily will malfunction 
if the user violates this. It just means that the designers have the 
freedom to introduce dependencies between the page writes if it makes the 
design easier/better/possible/whatever. It could very well be that for a 
given flash it is possible to do some writes out of order, but to avoid a) 
tying down the actual possibilities for a given flash and b) complicating 
the facts for the user they just specify that 'page writes must be 
executed in order'.

I must admit I wasn't aware of this fact either, but I have no hands-on 
experience with MLC flashes on the other hand.

> This makes /dev/mtdblock completely unusable as it reorders writes.
> Is /dev/mtdblock known to not work with MLC chips?

I don't think /dev/mtdblock reorders writes; isn't it just exposing the 
underlying /dev/mtd device as a block device essentially in order to make 
the mount command happy?

I would think the two most common uses of flash are either using a flash 
file system such as jffs2 or ubifs, and since each data node has its own 
header and identifier, there is no reason to do anything else but write 
the nodes in order within blocks, and the other use would be to store 
binary blobs, in which again the data would just be stored sequentially 
from start to end.

/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 apenwarr at gmail.com  Thu Oct  3 03:44:37 2013
From: apenwarr at gmail.com (Avery Pennarun)
Date: Thu, 3 Oct 2013 00:44:37 -0700
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <alpine.DEB.2.00.1310030932150.18310@lnxricardw.se.axis.com>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
 <l2grtn$svg$1@ger.gmane.org>
 <CAHqTa-3HxoQJ=wEZ_w8Vcp9VXS12=xNbiJ2v8fSsJbMb9BT_4w@mail.gmail.com>
 <alpine.DEB.2.00.1310030932150.18310@lnxricardw.se.axis.com>
Message-ID: <CAHqTa-1NhB4+zNkpSe3Ojw6ZywVBrxuPY1ZcWrN47nXeoBxWBg@mail.gmail.com>

On Thu, Oct 3, 2013 at 12:40 AM, Ricard Wanderlof
<ricard.wanderlof at axis.com> wrote:
> Just because they place the constraint on the user that the pages must be
> written in order doesn't mean that the device necessarily will malfunction
> if the user violates this. It just means that the designers have the freedom
> to introduce dependencies between the page writes if it makes the design
> easier/better/possible/whatever. It could very well be that for a given
> flash it is possible to do some writes out of order, but to avoid a) tying
> down the actual possibilities for a given flash and b) complicating the
> facts for the user they just specify that 'page writes must be executed in
> order'.
>
> I must admit I wasn't aware of this fact either, but I have no hands-on
> experience with MLC flashes on the other hand.

It seems rather under-documented to me, and I wouldn't be overly
surprised if it's not so much "standard behaviour" as "behaviour some
chip makers decided they could get away with based on usage patterns."
 But ok.

>> This makes /dev/mtdblock completely unusable as it reorders writes.
>> Is /dev/mtdblock known to not work with MLC chips?
>
> I don't think /dev/mtdblock reorders writes; isn't it just exposing the
> underlying /dev/mtd device as a block device essentially in order to make
> the mount command happy?
>
> I would think the two most common uses of flash are either using a flash
> file system such as jffs2 or ubifs, and since each data node has its own
> header and identifier, there is no reason to do anything else but write the
> nodes in order within blocks, and the other use would be to store binary
> blobs, in which again the data would just be stored sequentially from start
> to end.

/dev/mtdblock seems to do very complicated things.  For example, when
using it, you don't need to use flash_erase before writing to blocks.
Also, my device has 1024k eraseblocks, but if I do:

   dd if=/tmp/whatever of=/dev/mtdblock9 bs=1024k

it ends up *reading* from the flash, not just writing to it.  Given
how many ECC errors it also produces on my setup, I think it's also
reordering writes.  This isn't particularly surprising to me since as
soon as you go through the Linux block layer, you're at the mercy of
the disk I/O schedulers etc.  Perhaps it *mostly* won't reorder writes
in simple cases, but I don't think there's any guarantee of this.


From romain.izard.pro at gmail.com  Thu Oct  3 04:14:47 2013
From: romain.izard.pro at gmail.com (Romain Izard)
Date: Thu, 3 Oct 2013 10:14:47 +0200
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <CAHqTa-1NhB4+zNkpSe3Ojw6ZywVBrxuPY1ZcWrN47nXeoBxWBg@mail.gmail.com>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
 <l2grtn$svg$1@ger.gmane.org>
 <CAHqTa-3HxoQJ=wEZ_w8Vcp9VXS12=xNbiJ2v8fSsJbMb9BT_4w@mail.gmail.com>
 <alpine.DEB.2.00.1310030932150.18310@lnxricardw.se.axis.com>
 <CAHqTa-1NhB4+zNkpSe3Ojw6ZywVBrxuPY1ZcWrN47nXeoBxWBg@mail.gmail.com>
Message-ID: <CAMiSF3AdXYaJMd7qu0VM91e0g9CVOOdN0F_Ci4fwFrMacGLWFQ@mail.gmail.com>

2013/10/3 Avery Pennarun <apenwarr at gmail.com>:
> On Thu, Oct 3, 2013 at 12:40 AM, Ricard Wanderlof
> <ricard.wanderlof at axis.com> wrote:
>> Just because they place the constraint on the user that the pages must be
>> written in order doesn't mean that the device necessarily will malfunction
>> if the user violates this. It just means that the designers have the freedom
>> to introduce dependencies between the page writes if it makes the design
>> easier/better/possible/whatever. It could very well be that for a given
>> flash it is possible to do some writes out of order, but to avoid a) tying
>> down the actual possibilities for a given flash and b) complicating the
>> facts for the user they just specify that 'page writes must be executed in
>> order'.
>>
>> I must admit I wasn't aware of this fact either, but I have no hands-on
>> experience with MLC flashes on the other hand.
>
> It seems rather under-documented to me, and I wouldn't be overly
> surprised if it's not so much "standard behaviour" as "behaviour some
> chip makers decided they could get away with based on usage patterns."
>  But ok.
>

It's right there in the datasheet for both MLC manufacturers I have worked with.
And it seems that even SLC flash with large blocks [1] can also have the
same constraint.

There is very interesting technical presentation from Micron [2] that explains
all the issues with NAND flash, and that states that the write order
is necessary
to reduce the 'program disturb' issues.

[1] http://permalink.gmane.org/gmane.linux.drivers.mtd/20182
[2] https://www.micron.com/~/media/Documents/Products/Presentation/flash_mem_summit_jcooke_inconvenient_truths_nand.pdf

Regards,
-- 
Romain Izard


From kamlakant.patel at broadcom.com  Thu Oct  3 05:54:38 2013
From: kamlakant.patel at broadcom.com (Kamlakant Patel)
Date: Thu, 3 Oct 2013 15:24:38 +0530
Subject: [PATCH] Staging: MTD: Micron SPINAND Driver support
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA19568@DBDE04.ent.ti.com>
References: <1378128136-23699-1-git-send-email-kamlakant.patel@broadcom.com>
 <1380620038-25643-1-git-send-email-kamlakant.patel@broadcom.com>
 <20131002184547.GR23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA19568@DBDE04.ent.ti.com>
Message-ID: <20131003095437.GA15892@kpatel.netlogicmircro.com>

On Thu, Oct 03, 2013 at 05:49:58AM +0000, Gupta, Pekon wrote:
> > From: linux-mtd  On Behalf Of Brian Norris
> > > On Tue, Oct 01, 2013 at 03:03:58PM +0530, Kamlakant Patel wrote:
> > > This patch adds support for Micron SPINAND via MTD.
> > >
> > > Signed-off-by: Mona Anonuevo <manonuevo at micron.com>
> > > Signed-off-by: Kamlakant Patel <kamlakant.patel at broadcom.com>
> > > ---
> > > This patch has to be merged via staging tree.
> > >
> > > This is a driver from Micron for MT29F1G01ZACH4 SPI based NAND chips.
> > This driver had
> > > been posted multiple times to the mtd list.
> > > 1. http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
> > > 2. http://lists.infradead.org/pipermail/linux-mtd/2010-April/029523.html
> > > 3. patchwork.ozlabs.org/patch/258697/
> > > This has not been merged into the main kernel yet.
> > >
> > > I have cleaned and updated it for current kernel. Since there are many
> > users for
> > > this driver, it may be useful to add it to the staging tree, where further fixes
> > and
> > > cleanups can be done. Once it reaches to the standard will be moved to the
> > mtd.
> > >
> > > This driver has been tested with Micron SPINAND MT29F1G01ZACH4 chip
> > on kernel 3.12 on
> > > the Netlogic XLP platforms.
> > >
> > > Mona Anonuevo, I have retained your sign-offs from the original patch.
> > >
> I see that major portion (especially the generic framework) is ported from
> http://lists.infradead.org/pipermail/linux-mtd/2010-May/031975.html
> So shouldn't you just maintain the original authorship ?
> And the original headers ?
> 

I have retained signoff, module_author name and copyright from the
original patch. There are significant changes in the code, so
it will not be correct to keep the commit author.

> > 
> > You can address these comments in follow up patches after it's included
> > in staging, though. There's probably more review needed anyway
> > eventually (I see that no one really has reviewed this on the MTD
> > mailing list yet).
> > 
> The original version of this patch in 2010 added *generic spinand*
> framework. And support for m29f (Micron devices) should have been
> added using that generic framework. But due to lack of response
> generic framework never went in.
> Therefore I think this patch series adds a customized driver just for
> 'm29f' (Micron serial NAND) devices, removing the generalization.
> 
> There was a refreshed version of original patch (with generic framework)
> but no response on that too. I don't want to hold this patch, but it would
> be good, if you can review generic framework also ..
> https://lkml.org/lkml/2013/6/26/88

Right now, we don't want do merge the framework code into staging, that
has to go through linux-mtd after discussion. This patch is to add a
working driver for mt29f chip using the existing NAND framework.

> 
> with regards, pekon
> 



From christian.riesch at omicron.at  Thu Oct  3 07:14:34 2013
From: christian.riesch at omicron.at (Christian Riesch)
Date: Thu, 3 Oct 2013 13:14:34 +0200
Subject: [RESEND PATCH 0/2] mtd: Harmonize implementations of OTP write and
 _get_{fact, user}_prot_info
Message-ID: <d11cf30b-a84f-44cf-a7b8-81c5e846a64a@mary.at.omicron.at>

Hi all,

In the discussion on my patchset for the OTP support for
drivers/mtd/chips/cfi_cmdset_0002.c [1-5], Artem requested two changes in the
current code of the OTP write functions and the _get_{fact,user}_prot_info
code.

These two patches are an attempt to make the requested changes.

The first patch adds a retlen parameter to the _get_fact_prot_info and
_get_user_prot_info functions and thus harmonizes the implementation
with those of the write and read functions.

The second patch fixes a problem that I earlier addressed in [1]. After
the discussion about this patch on the mtd mailing list, I think that the
correct behavior of the write function should be the one specified in [6]:
Try to write as many bytes as possible and return the number of bytes
that were written. If no data could be written due to lack of OTP memory,
return -ENOSPC.

Artem, would you please have a look at these patches? I would like to know
if I understood you correctly, or if I missed something here. Please note
that I cannot test these patches since I do not have the hardware. The
patches are compile tested only. If these patches are ok, I will also
respin the OTP support patches for cfi_cmdset_0002.

Thank you!

Best regards,
Christian

[1] http://patchwork.ozlabs.org/patch/239897/
[2] http://patchwork.ozlabs.org/patch/240010/
[3] http://patchwork.ozlabs.org/patch/240007/
[4] http://patchwork.ozlabs.org/patch/240008/
[5] http://patchwork.ozlabs.org/patch/240009/
[6] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html

Cc: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Cc: Kyungmin Park <kyungmin.park at samsung.com>
Cc: Amul Kumar Saha <amul.saha at samsung.com>

Christian Riesch (2):
  mtd: Add a retlen parameter to _get_{fact,user}_prot_info
  mtd: Fix the behavior of otp write if there is not enough room for
    data

 drivers/mtd/chips/cfi_cmdset_0001.c |   44 +++++++++++++++++++----------------
 drivers/mtd/devices/mtd_dataflash.c |   20 +++++++---------
 drivers/mtd/mtdchar.c               |   18 ++++++++++----
 drivers/mtd/mtdcore.c               |   12 +++++-----
 drivers/mtd/mtdpart.c               |   14 ++++++-----
 drivers/mtd/onenand/onenand_base.c  |   41 +++++++++++++++++---------------
 include/linux/mtd/mtd.h             |   16 ++++++-------
 7 files changed, 90 insertions(+), 75 deletions(-)

-- 
1.7.9.5



From christian.riesch at omicron.at  Thu Oct  3 07:14:35 2013
From: christian.riesch at omicron.at (Christian Riesch)
Date: Thu, 3 Oct 2013 13:14:35 +0200
Subject: [RESEND PATCH 1/2] mtd: Add a retlen parameter to _get_{fact,
 user}_prot_info
In-Reply-To: <1380798876-3321-1-git-send-email-christian.riesch@omicron.at>
References: <1380798876-3321-1-git-send-email-christian.riesch@omicron.at>
Message-ID: <9c3c8484-54a4-40e3-8a32-2b01c33280ac@mary.at.omicron.at>

Signed-off-by: Christian Riesch <christian.riesch at omicron.at>
Cc: Artem Bityutskiy <Artem.Bityutskiy at linux.intel.com>
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   31 +++++++++++++------------------
 drivers/mtd/devices/mtd_dataflash.c |    7 ++++---
 drivers/mtd/mtdchar.c               |   11 ++++++-----
 drivers/mtd/mtdcore.c               |   12 ++++++------
 drivers/mtd/mtdpart.c               |   14 ++++++++------
 drivers/mtd/onenand/onenand_base.c  |   30 ++++++++++++------------------
 include/linux/mtd/mtd.h             |   16 ++++++++--------
 7 files changed, 57 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 7751443..2378e2f 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -69,10 +69,10 @@ static int cfi_intelext_read_fact_prot_reg (struct mtd_info *, loff_t, size_t, s
 static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_write_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
 static int cfi_intelext_lock_user_prot_reg (struct mtd_info *, loff_t, size_t);
-static int cfi_intelext_get_fact_prot_info (struct mtd_info *,
-					    struct otp_info *, size_t);
-static int cfi_intelext_get_user_prot_info (struct mtd_info *,
-					    struct otp_info *, size_t);
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+					   size_t *, struct otp_info *);
+static int cfi_intelext_get_user_prot_info(struct mtd_info *, size_t,
+					   size_t *, struct otp_info *);
 #endif
 static int cfi_intelext_suspend (struct mtd_info *);
 static void cfi_intelext_resume (struct mtd_info *);
@@ -2399,24 +2399,19 @@ static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
 				     NULL, do_otp_lock, 1);
 }
 
-static int cfi_intelext_get_fact_prot_info(struct mtd_info *mtd,
-					   struct otp_info *buf, size_t len)
-{
-	size_t retlen;
-	int ret;
+static int cfi_intelext_get_fact_prot_info(struct mtd_info *, size_t,
+					   size_t *, struct otp_info *);
 
-	ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 0);
-	return ret ? : retlen;
+{
+	return cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf,
+				     NULL, 0);
 }
 
-static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd,
-					   struct otp_info *buf, size_t len)
+static int cfi_intelext_get_user_prot_info(struct mtd_info *mtd, size_t len,
+					   size_t *retlen, struct otp_info *buf)
 {
-	size_t retlen;
-	int ret;
-
-	ret = cfi_intelext_otp_walk(mtd, 0, len, &retlen, (u_char *)buf, NULL, 1);
-	return ret ? : retlen;
+	return cfi_intelext_otp_walk(mtd, 0, len, retlen, (u_char *)buf,
+				     NULL, 1);
 }
 
 #endif
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 28779b6..09c69ce 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -442,8 +442,8 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
 
 #ifdef CONFIG_MTD_DATAFLASH_OTP
 
-static int dataflash_get_otp_info(struct mtd_info *mtd,
-		struct otp_info *info, size_t len)
+static int dataflash_get_otp_info(struct mtd_info *mtd, size_t len,
+				  size_t *retlen, struct otp_info *info)
 {
 	/* Report both blocks as identical:  bytes 0..64, locked.
 	 * Unless the user block changed from all-ones, we can't
@@ -452,7 +452,8 @@ static int dataflash_get_otp_info(struct mtd_info *mtd,
 	info->start = 0;
 	info->length = 64;
 	info->locked = 1;
-	return sizeof(*info);
+	*retlen = sizeof(*info);
+	return 0;
 }
 
 static ssize_t otp_read(struct spi_device *spi, unsigned base,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..0edb0ca 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -888,25 +888,26 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 	case OTPGETREGIONINFO:
 	{
 		struct otp_info *buf = kmalloc(4096, GFP_KERNEL);
+		size_t retlen;
 		if (!buf)
 			return -ENOMEM;
 		switch (mfi->mode) {
 		case MTD_FILE_MODE_OTP_FACTORY:
-			ret = mtd_get_fact_prot_info(mtd, buf, 4096);
+			ret = mtd_get_fact_prot_info(mtd, 4096, &retlen, buf);
 			break;
 		case MTD_FILE_MODE_OTP_USER:
-			ret = mtd_get_user_prot_info(mtd, buf, 4096);
+			ret = mtd_get_user_prot_info(mtd, 4096, &retlen, buf);
 			break;
 		default:
 			ret = -EINVAL;
 			break;
 		}
-		if (ret >= 0) {
+		if (!ret) {
 			if (cmd == OTPGETREGIONCOUNT) {
-				int nbr = ret / sizeof(struct otp_info);
+				int nbr = retlen / sizeof(struct otp_info);
 				ret = copy_to_user(argp, &nbr, sizeof(int));
 			} else
-				ret = copy_to_user(argp, buf, ret);
+				ret = copy_to_user(argp, buf, retlen);
 			if (ret)
 				ret = -EFAULT;
 		}
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 048c823..d0c3d41 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -877,14 +877,14 @@ EXPORT_SYMBOL_GPL(mtd_read_oob);
  * devices. The user data is one time programmable but the factory data is read
  * only.
  */
-int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-			   size_t len)
+int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+			   struct otp_info *buf)
 {
 	if (!mtd->_get_fact_prot_info)
 		return -EOPNOTSUPP;
 	if (!len)
 		return 0;
-	return mtd->_get_fact_prot_info(mtd, buf, len);
+	return mtd->_get_fact_prot_info(mtd, len, retlen, buf);
 }
 EXPORT_SYMBOL_GPL(mtd_get_fact_prot_info);
 
@@ -900,14 +900,14 @@ int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
 }
 EXPORT_SYMBOL_GPL(mtd_read_fact_prot_reg);
 
-int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-			   size_t len)
+int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+			   struct otp_info *buf)
 {
 	if (!mtd->_get_user_prot_info)
 		return -EOPNOTSUPP;
 	if (!len)
 		return 0;
-	return mtd->_get_user_prot_info(mtd, buf, len);
+	return mtd->_get_user_prot_info(mtd, len, retlen, buf);
 }
 EXPORT_SYMBOL_GPL(mtd_get_user_prot_info);
 
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 3014933..57d8cf7 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -150,11 +150,12 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
 						 retlen, buf);
 }
 
-static int part_get_user_prot_info(struct mtd_info *mtd,
-		struct otp_info *buf, size_t len)
+static int part_get_user_prot_info(struct mtd_info *mtd, size_t len,
+				   size_t *retlen, struct otp_info *buf)
 {
 	struct mtd_part *part = PART(mtd);
-	return part->master->_get_user_prot_info(part->master, buf, len);
+	return part->master->_get_user_prot_info(part->master, len, retlen,
+						 buf);
 }
 
 static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
@@ -165,11 +166,12 @@ static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
 						 retlen, buf);
 }
 
-static int part_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-		size_t len)
+static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+				   size_t *retlen, struct otp_info *buf)
 {
 	struct mtd_part *part = PART(mtd);
-	return part->master->_get_fact_prot_info(part->master, buf, len);
+	return part->master->_get_fact_prot_info(part->master, len, retlen,
+						 buf);
 }
 
 static int part_write(struct mtd_info *mtd, loff_t to, size_t len,
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index b3f41f2..419c538 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3242,20 +3242,17 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len,
 /**
  * onenand_get_fact_prot_info - [MTD Interface] Read factory OTP info
  * @param mtd		MTD device structure
- * @param buf		the databuffer to put/get data
  * @param len		number of bytes to read
+ * @param retlen	pointer to variable to store the number of read bytes
+ * @param buf		the databuffer to put/get data
  *
  * Read factory OTP info.
  */
-static int onenand_get_fact_prot_info(struct mtd_info *mtd,
-			struct otp_info *buf, size_t len)
+static int onenand_get_fact_prot_info(struct mtd_info *mtd, size_t len,
+				      size_t *retlen, struct otp_info *buf)
 {
-	size_t retlen;
-	int ret;
-
-	ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_FACTORY);
-
-	return ret ? : retlen;
+	return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
+				MTD_OTP_FACTORY);
 }
 
 /**
@@ -3277,20 +3274,17 @@ static int onenand_read_fact_prot_reg(struct mtd_info *mtd, loff_t from,
 /**
  * onenand_get_user_prot_info - [MTD Interface] Read user OTP info
  * @param mtd		MTD device structure
- * @param buf		the databuffer to put/get data
+ * @param retlen	pointer to variable to store the number of read bytes
  * @param len		number of bytes to read
+ * @param buf		the databuffer to put/get data
  *
  * Read user OTP info.
  */
-static int onenand_get_user_prot_info(struct mtd_info *mtd,
-			struct otp_info *buf, size_t len)
+static int onenand_get_user_prot_info(struct mtd_info *mtd, size_t len,
+				      size_t *retlen, struct otp_info *buf)
 {
-	size_t retlen;
-	int ret;
-
-	ret = onenand_otp_walk(mtd, 0, len, &retlen, (u_char *) buf, NULL, MTD_OTP_USER);
-
-	return ret ? : retlen;
+	return onenand_otp_walk(mtd, 0, len, retlen, (u_char *) buf, NULL,
+				MTD_OTP_USER);
 }
 
 /**
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index a5cf4e8..af35068 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -204,12 +204,12 @@ struct mtd_info {
 			  struct mtd_oob_ops *ops);
 	int (*_write_oob) (struct mtd_info *mtd, loff_t to,
 			   struct mtd_oob_ops *ops);
-	int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
-				    size_t len);
+	int (*_get_fact_prot_info) (struct mtd_info *mtd, size_t len,
+				    size_t *retlen, struct otp_info *buf);
 	int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
 				    size_t len, size_t *retlen, u_char *buf);
-	int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
-				    size_t len);
+	int (*_get_user_prot_info) (struct mtd_info *mtd, size_t len,
+				    size_t *retlen, struct otp_info *buf);
 	int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
 				    size_t len, size_t *retlen, u_char *buf);
 	int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
@@ -278,12 +278,12 @@ static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
 	return mtd->_write_oob(mtd, to, ops);
 }
 
-int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-			   size_t len);
+int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+			   struct otp_info *buf);
 int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
 			   size_t *retlen, u_char *buf);
-int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf,
-			   size_t len);
+int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen,
+			   struct otp_info *buf);
 int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len,
 			   size_t *retlen, u_char *buf);
 int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
-- 
1.7.9.5



From christian.riesch at omicron.at  Thu Oct  3 07:14:36 2013
From: christian.riesch at omicron.at (Christian Riesch)
Date: Thu, 3 Oct 2013 13:14:36 +0200
Subject: [RESEND PATCH 2/2] mtd: Fix the behavior of otp write if there is not
 enough room for data
In-Reply-To: <1380798876-3321-1-git-send-email-christian.riesch@omicron.at>
References: <1380798876-3321-1-git-send-email-christian.riesch@omicron.at>
Message-ID: <10b23e42-0ff3-4f70-8966-15aba66d5576@mary.at.omicron.at>

An OTP write shall write as much data as possible to the OTP memory
and return the number of bytes that have actually been written.
If no data could be written at all due to lack of OTP memory,
return -ENOSPC.

Signed-off-by: Christian Riesch <christian.riesch at omicron.at>
Cc: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
Cc: Kyungmin Park <kyungmin.park at samsung.com>
Cc: Amul Kumar Saha <amul.saha at samsung.com>
---
 drivers/mtd/chips/cfi_cmdset_0001.c |   13 +++++++++++--
 drivers/mtd/devices/mtd_dataflash.c |   13 +++++--------
 drivers/mtd/mtdchar.c               |    7 +++++++
 drivers/mtd/onenand/onenand_base.c  |   11 ++++++++++-
 4 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 2378e2f..6efc22d 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2387,8 +2387,17 @@ static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
 					    size_t len, size_t *retlen,
 					     u_char *buf)
 {
-	return cfi_intelext_otp_walk(mtd, from, len, retlen,
-				     buf, do_otp_write, 1);
+	int ret;
+
+	ret = cfi_intelext_otp_walk(mtd, from, len, retlen,
+				    buf, do_otp_write, 1);
+
+	/* if no data could be written due to lack of OTP memory,
+	   return ENOSPC */
+	if (!ret && len && !(*retlen))
+		return -ENOSPC;
+
+	return ret;
 }
 
 static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd,
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 09c69ce..5236d85 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
 	struct dataflash	*priv = mtd->priv;
 	int			status;
 
-	if (len > 64)
-		return -EINVAL;
-
-	/* Strictly speaking, we *could* truncate the write ... but
-	 * let's not do that for the only write that's ever possible.
-	 */
-	if ((from + len) > 64)
-		return -EINVAL;
+	if ((from + len) > 64) {
+		len = 64 - from;
+		if (len <= 0)
+			return -ENOSPC;
+	}
 
 	/* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
 	 * IN:  ignore all
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 0edb0ca..db99031 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -323,6 +323,13 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c
 		default:
 			ret = mtd_write(mtd, *ppos, len, &retlen, kbuf);
 		}
+		/* return -ENOSPC only if no data was written */
+		if ((ret == -ENOSPC) && (total_retlen)) {
+			ret = 0;
+			retlen = 0;
+			/* drop the remaining data */
+			count = 0;
+		}
 		if (!ret) {
 			*ppos += retlen;
 			total_retlen += retlen;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 419c538..9d47c2c 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -3316,7 +3316,16 @@ static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from,
 static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from,
 			size_t len, size_t *retlen, u_char *buf)
 {
-	return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER);
+	int ret;
+	ret = onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write,
+			       MTD_OTP_USER);
+
+	/* if no data could be written due to lack of OTP memory,
+	   return ENOSPC */
+	if (!ret && len && !(*retlen))
+		return -ENOSPC;
+
+	return ret;
 }
 
 /**
-- 
1.7.9.5



From dedekind1 at gmail.com  Thu Oct  3 10:34:43 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 03 Oct 2013 17:34:43 +0300
Subject: [PATCH v4 05/12] mtd: nand: print out the cell information for
 nand chip
In-Reply-To: <20130930224942.GO23337@ld-irv-0074.broadcom.com>
References: <1380092301-21924-1-git-send-email-b32955@freescale.com>
 <1380092301-21924-6-git-send-email-b32955@freescale.com>
 <20130930224942.GO23337@ld-irv-0074.broadcom.com>
Message-ID: <1380810883.27358.432.camel@sauron.fi.intel.com>

On Mon, 2013-09-30 at 15:49 -0700, Brian Norris wrote:
> On Wed, Sep 25, 2013 at 02:58:14PM +0800, Huang Shijie wrote:
> > Print out the cell information for nand chip.
> > 
> > (Since the message is too long, this patch also splits the log
> > with two separate pr_info())
> > 
> > Signed-off-by: Huang Shijie <b32955 at freescale.com>
> > ---
> >  drivers/mtd/nand/nand_base.c |   11 +++++++----
> >  1 files changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
> > index 94d9084..b94309b 100644
> > --- a/drivers/mtd/nand/nand_base.c
> > +++ b/drivers/mtd/nand/nand_base.c
> > @@ -3460,11 +3460,14 @@ ident_done:
> >  	if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
> >  		chip->cmdfunc = nand_command_lp;
> >  
> > -	pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
> > -		" %dMiB, page size: %d, OOB size: %d\n",
> > +	pr_info("NAND device: Manufacturer ID: 0x%02x,"
> > +			"Chip ID: 0x%02x (%s %s) \n",
> 
> You're adding excess whitespace before the '\n'. I'll squash this
> myself.

Nowadays' fashion is to never split strings, Huang.

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Thu Oct  3 11:00:14 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 03 Oct 2013 18:00:14 +0300
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <1380376516-30144-2-git-send-email-richard@nod.at>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
Message-ID: <1380812414.27358.440.camel@sauron.fi.intel.com>

On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
> If no free PEBs are available refill_wl_user_pool() must not
> return with -ENOSPC immediately.
> It has to block till produce_free_peb() produced a free PEB.
> 
> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
> Signed-off-by: Richard Weinberger <richard at nod.at>

What is pool size, I wonder?

-- 
Best Regards,
Artem Bityutskiy



From richard at nod.at  Thu Oct  3 11:08:41 2013
From: richard at nod.at (Richard Weinberger)
Date: Thu, 03 Oct 2013 17:08:41 +0200
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <1380812414.27358.440.camel@sauron.fi.intel.com>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com>
Message-ID: <524D8879.1030203@nod.at>

Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
> On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
>> If no free PEBs are available refill_wl_user_pool() must not
>> return with -ENOSPC immediately.
>> It has to block till produce_free_peb() produced a free PEB.
>>
>> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
>> Signed-off-by: Richard Weinberger <richard at nod.at>
> 
> What is pool size, I wonder?

Currently it's 25 (UBI_FM_WL_POOL_SIZE).
If experience shows that 25 is too low/big we can change this constant.
Maybe it's also worth making them configurable...

Thanks,
//richard


From ricard.wanderlof at axis.com  Thu Oct  3 11:26:11 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Thu, 3 Oct 2013 17:26:11 +0200
Subject: Page corruption when writing non-sequential pages in an MLC NAND
 eraseblock
In-Reply-To: <CAMiSF3AdXYaJMd7qu0VM91e0g9CVOOdN0F_Ci4fwFrMacGLWFQ@mail.gmail.com>
References: <CAHqTa-0d=U+W2nju8WeCJ=gL+ja8DVuK0BUquajOL6qXV5C0+g@mail.gmail.com>
 <l2grtn$svg$1@ger.gmane.org>
 <CAHqTa-3HxoQJ=wEZ_w8Vcp9VXS12=xNbiJ2v8fSsJbMb9BT_4w@mail.gmail.com>
 <alpine.DEB.2.00.1310030932150.18310@lnxricardw.se.axis.com>
 <CAHqTa-1NhB4+zNkpSe3Ojw6ZywVBrxuPY1ZcWrN47nXeoBxWBg@mail.gmail.com>
 <CAMiSF3AdXYaJMd7qu0VM91e0g9CVOOdN0F_Ci4fwFrMacGLWFQ@mail.gmail.com>
Message-ID: <alpine.DEB.2.00.1310031723490.18310@lnxricardw.se.axis.com>


On Thu, 3 Oct 2013, Romain Izard wrote:

> It's right there in the datasheet for both MLC manufacturers I have worked with.
> And it seems that even SLC flash with large blocks [1] can also have the
> same constraint.
>
> There is very interesting technical presentation from Micron [2] that explains
> all the issues with NAND flash, and that states that the write order
> is necessary
> to reduce the 'program disturb' issues.
>
> [1] http://permalink.gmane.org/gmane.linux.drivers.mtd/20182
> [2] https://www.micron.com/~/media/Documents/Products/Presentation/flash_mem_summit_jcooke_inconvenient_truths_nand.pdf

Interesting, I hadn't heard that sequential writes were a requirement for 
large-page SLC flash. I just checked the data sheet for a Samsung K9F1208 
and it doesn't mention it at all. That's just one of many of course, and 
it could still be that sequential writes reduce the likelyhood of program 
disturb errors.

/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 dedekind1 at gmail.com  Thu Oct  3 11:27:51 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 03 Oct 2013 18:27:51 +0300
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <524D8879.1030203@nod.at>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com> <524D8879.1030203@nod.at>
Message-ID: <1380814071.27358.444.camel@sauron.fi.intel.com>

On Thu, 2013-10-03 at 17:08 +0200, Richard Weinberger wrote:
> Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
> > On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
> >> If no free PEBs are available refill_wl_user_pool() must not
> >> return with -ENOSPC immediately.
> >> It has to block till produce_free_peb() produced a free PEB.
> >>
> >> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
> >> Signed-off-by: Richard Weinberger <richard at nod.at>
> > 
> > What is pool size, I wonder?
> 
> Currently it's 25 (UBI_FM_WL_POOL_SIZE).
> If experience shows that 25 is too low/big we can change this constant.
> Maybe it's also worth making them configurable...

I if it is a possible scenario that this function will not return until
25 (or even 10) PEBs are erased? 

-- 
Best Regards,
Artem Bityutskiy



From richard at nod.at  Thu Oct  3 11:53:12 2013
From: richard at nod.at (Richard Weinberger)
Date: Thu, 03 Oct 2013 17:53:12 +0200
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <1380814071.27358.444.camel@sauron.fi.intel.com>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com> <524D8879.1030203@nod.at>
 <1380814071.27358.444.camel@sauron.fi.intel.com>
Message-ID: <524D92E8.1030704@nod.at>

Am 03.10.2013 17:27, schrieb Artem Bityutskiy:
> On Thu, 2013-10-03 at 17:08 +0200, Richard Weinberger wrote:
>> Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
>>> On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
>>>> If no free PEBs are available refill_wl_user_pool() must not
>>>> return with -ENOSPC immediately.
>>>> It has to block till produce_free_peb() produced a free PEB.
>>>>
>>>> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
>>>> Signed-off-by: Richard Weinberger <richard at nod.at>
>>>
>>> What is pool size, I wonder?
>>
>> Currently it's 25 (UBI_FM_WL_POOL_SIZE).
>> If experience shows that 25 is too low/big we can change this constant.
>> Maybe it's also worth making them configurable...
> 
> I if it is a possible scenario that this function will not return until
> 25 (or even 10) PEBs are erased? 
> 

Sure. It will try to gain up to 25 PEBs but return if it gets less.
That's why a pool has a current and a max size.

Thanks,
//richard


From computersforpeace at gmail.com  Thu Oct  3 11:53:28 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 03 Oct 2013 08:53:28 -0700
Subject: [PATCH v4 05/12] mtd: nand: print out the cell information for
 nand chip
In-Reply-To: <1380810883.27358.432.camel@sauron.fi.intel.com>
References: <1380092301-21924-1-git-send-email-b32955@freescale.com>	
 <1380092301-21924-6-git-send-email-b32955@freescale.com>	
 <20130930224942.GO23337@ld-irv-0074.broadcom.com>
 <1380810883.27358.432.camel@sauron.fi.intel.com>
Message-ID: <524D92F8.70603@gmail.com>

On 10/03/2013 07:34 AM, Artem Bityutskiy wrote:
> On Mon, 2013-09-30 at 15:49 -0700, Brian Norris wrote:
>> On Wed, Sep 25, 2013 at 02:58:14PM +0800, Huang Shijie wrote:
>>> Print out the cell information for nand chip.
>>>
>>> (Since the message is too long, this patch also splits the log
>>> with two separate pr_info())
>>>
>>> Signed-off-by: Huang Shijie <b32955 at freescale.com>
>>> ---
>>>   drivers/mtd/nand/nand_base.c |   11 +++++++----
>>>   1 files changed, 7 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
>>> index 94d9084..b94309b 100644
>>> --- a/drivers/mtd/nand/nand_base.c
>>> +++ b/drivers/mtd/nand/nand_base.c
>>> @@ -3460,11 +3460,14 @@ ident_done:
>>>   	if (mtd->writesize > 512 && chip->cmdfunc == nand_command)
>>>   		chip->cmdfunc = nand_command_lp;
>>>
>>> -	pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s),"
>>> -		" %dMiB, page size: %d, OOB size: %d\n",
>>> +	pr_info("NAND device: Manufacturer ID: 0x%02x,"
>>> +			"Chip ID: 0x%02x (%s %s) \n",
>>
>> You're adding excess whitespace before the '\n'. I'll squash this
>> myself.
>
> Nowadays' fashion is to never split strings, Huang.

checkpatch.pl actually warns about this now, so I already fixed it but 
didn't remember to mention it. Also, in splitting this string, Huang 
removed a space (fixed as well).

Brian


From dedekind1 at gmail.com  Thu Oct  3 12:00:35 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 03 Oct 2013 19:00:35 +0300
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <524D92E8.1030704@nod.at>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com> <524D8879.1030203@nod.at>
 <1380814071.27358.444.camel@sauron.fi.intel.com> <524D92E8.1030704@nod.at>
Message-ID: <1380816035.27358.447.camel@sauron.fi.intel.com>

On Thu, 2013-10-03 at 17:53 +0200, Richard Weinberger wrote:
> Am 03.10.2013 17:27, schrieb Artem Bityutskiy:
> > On Thu, 2013-10-03 at 17:08 +0200, Richard Weinberger wrote:
> >> Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
> >>> On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
> >>>> If no free PEBs are available refill_wl_user_pool() must not
> >>>> return with -ENOSPC immediately.
> >>>> It has to block till produce_free_peb() produced a free PEB.
> >>>>
> >>>> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
> >>>> Signed-off-by: Richard Weinberger <richard at nod.at>
> >>>
> >>> What is pool size, I wonder?
> >>
> >> Currently it's 25 (UBI_FM_WL_POOL_SIZE).
> >> If experience shows that 25 is too low/big we can change this constant.
> >> Maybe it's also worth making them configurable...
> > 
> > I if it is a possible scenario that this function will not return until
> > 25 (or even 10) PEBs are erased? 
> > 
> 
> Sure. It will try to gain up to 25 PEBs but return if it gets less.
> That's why a pool has a current and a max size.

So if erasing speed is say, 250ms, then it would take 6.25 seconds?

-- 
Best Regards,
Artem Bityutskiy



From richard at nod.at  Thu Oct  3 12:35:45 2013
From: richard at nod.at (Richard Weinberger)
Date: Thu, 03 Oct 2013 18:35:45 +0200
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <1380816035.27358.447.camel@sauron.fi.intel.com>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com> <524D8879.1030203@nod.at>
 <1380814071.27358.444.camel@sauron.fi.intel.com> <524D92E8.1030704@nod.at>
 <1380816035.27358.447.camel@sauron.fi.intel.com>
Message-ID: <524D9CE1.8040600@nod.at>

Am 03.10.2013 18:00, schrieb Artem Bityutskiy:
> On Thu, 2013-10-03 at 17:53 +0200, Richard Weinberger wrote:
>> Am 03.10.2013 17:27, schrieb Artem Bityutskiy:
>>> On Thu, 2013-10-03 at 17:08 +0200, Richard Weinberger wrote:
>>>> Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
>>>>> On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
>>>>>> If no free PEBs are available refill_wl_user_pool() must not
>>>>>> return with -ENOSPC immediately.
>>>>>> It has to block till produce_free_peb() produced a free PEB.
>>>>>>
>>>>>> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
>>>>>> Signed-off-by: Richard Weinberger <richard at nod.at>
>>>>>
>>>>> What is pool size, I wonder?
>>>>
>>>> Currently it's 25 (UBI_FM_WL_POOL_SIZE).
>>>> If experience shows that 25 is too low/big we can change this constant.
>>>> Maybe it's also worth making them configurable...
>>>
>>> I if it is a possible scenario that this function will not return until
>>> 25 (or even 10) PEBs are erased? 
>>>
>>
>> Sure. It will try to gain up to 25 PEBs but return if it gets less.
>> That's why a pool has a current and a max size.
> 
> So if erasing speed is say, 250ms, then it would take 6.25 seconds?

Only in the very worst case if we have to call 25 times produce_free_peb().

Of course we could add a check to return immediately if produce_free_peb()
got called a few times in series.
But I really would like to wait with such performance tweaks until fastmap
is more mature.

Thanks,
//richard


From dedekind1 at gmail.com  Thu Oct  3 12:41:55 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 03 Oct 2013 19:41:55 +0300
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <524D9CE1.8040600@nod.at>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com>
 <524D8879.1030203@nod.at>  <1380814071.27358.444.camel@sauron.fi.intel.com>
 <524D92E8.1030704@nod.at> <1380816035.27358.447.camel@sauron.fi.intel.com>
 <524D9CE1.8040600@nod.at>
Message-ID: <1380818515.18862.0.camel@sauron.fi.intel.com>

On Thu, 2013-10-03 at 18:35 +0200, Richard Weinberger wrote:
> Am 03.10.2013 18:00, schrieb Artem Bityutskiy:
> > On Thu, 2013-10-03 at 17:53 +0200, Richard Weinberger wrote:
> >> Am 03.10.2013 17:27, schrieb Artem Bityutskiy:
> >>> On Thu, 2013-10-03 at 17:08 +0200, Richard Weinberger wrote:
> >>>> Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
> >>>>> On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
> >>>>>> If no free PEBs are available refill_wl_user_pool() must not
> >>>>>> return with -ENOSPC immediately.
> >>>>>> It has to block till produce_free_peb() produced a free PEB.
> >>>>>>
> >>>>>> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
> >>>>>> Signed-off-by: Richard Weinberger <richard at nod.at>
> >>>>>
> >>>>> What is pool size, I wonder?
> >>>>
> >>>> Currently it's 25 (UBI_FM_WL_POOL_SIZE).
> >>>> If experience shows that 25 is too low/big we can change this constant.
> >>>> Maybe it's also worth making them configurable...
> >>>
> >>> I if it is a possible scenario that this function will not return until
> >>> 25 (or even 10) PEBs are erased? 
> >>>
> >>
> >> Sure. It will try to gain up to 25 PEBs but return if it gets less.
> >> That's why a pool has a current and a max size.
> > 
> > So if erasing speed is say, 250ms, then it would take 6.25 seconds?
> 
> Only in the very worst case if we have to call 25 times produce_free_peb().
> 
> Of course we could add a check to return immediately if produce_free_peb()
> got called a few times in series.
> But I really would like to wait with such performance tweaks until fastmap
> is more mature.

OK, but how about at least adding a comment talking about this unlikely
scenario?

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Thu Oct  3 12:44:14 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 03 Oct 2013 19:44:14 +0300
Subject: UBI fastmap updates
In-Reply-To: <1380376516-30144-1-git-send-email-richard@nod.at>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
Message-ID: <1380818654.18862.1.camel@sauron.fi.intel.com>

On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
> this series is a collection of all pending UBI fastmap updates.
> 
> Richard Genoud found issues in combination with U-Boot.
> These issues also uncovered other minor issues in some error paths.
> Only one fix is not really fastmap specific and touches generic 
> UBI code, "UBI: simplify image sequence test".
> 

Pushed to linux-ubi, thanks!

-- 
Best Regards,
Artem Bityutskiy



From richard at nod.at  Thu Oct  3 12:48:23 2013
From: richard at nod.at (Richard Weinberger)
Date: Thu, 03 Oct 2013 18:48:23 +0200
Subject: [PATCH 1/7] UBI: fix refill_wl_user_pool()
In-Reply-To: <1380818515.18862.0.camel@sauron.fi.intel.com>
References: <1380376516-30144-1-git-send-email-richard@nod.at>
 <1380376516-30144-2-git-send-email-richard@nod.at>
 <1380812414.27358.440.camel@sauron.fi.intel.com> <524D8879.1030203@nod.at>
 <1380814071.27358.444.camel@sauron.fi.intel.com> <524D92E8.1030704@nod.at>
 <1380816035.27358.447.camel@sauron.fi.intel.com> <524D9CE1.8040600@nod.at>
 <1380818515.18862.0.camel@sauron.fi.intel.com>
Message-ID: <524D9FD7.5050406@nod.at>

Am 03.10.2013 18:41, schrieb Artem Bityutskiy:
> On Thu, 2013-10-03 at 18:35 +0200, Richard Weinberger wrote:
>> Am 03.10.2013 18:00, schrieb Artem Bityutskiy:
>>> On Thu, 2013-10-03 at 17:53 +0200, Richard Weinberger wrote:
>>>> Am 03.10.2013 17:27, schrieb Artem Bityutskiy:
>>>>> On Thu, 2013-10-03 at 17:08 +0200, Richard Weinberger wrote:
>>>>>> Am 03.10.2013 17:00, schrieb Artem Bityutskiy:
>>>>>>> On Sat, 2013-09-28 at 15:55 +0200, Richard Weinberger wrote:
>>>>>>>> If no free PEBs are available refill_wl_user_pool() must not
>>>>>>>> return with -ENOSPC immediately.
>>>>>>>> It has to block till produce_free_peb() produced a free PEB.
>>>>>>>>
>>>>>>>> Reported-and-Tested-by: Richard Genoud <richard.genoud at gmail.com>
>>>>>>>> Signed-off-by: Richard Weinberger <richard at nod.at>
>>>>>>>
>>>>>>> What is pool size, I wonder?
>>>>>>
>>>>>> Currently it's 25 (UBI_FM_WL_POOL_SIZE).
>>>>>> If experience shows that 25 is too low/big we can change this constant.
>>>>>> Maybe it's also worth making them configurable...
>>>>>
>>>>> I if it is a possible scenario that this function will not return until
>>>>> 25 (or even 10) PEBs are erased? 
>>>>>
>>>>
>>>> Sure. It will try to gain up to 25 PEBs but return if it gets less.
>>>> That's why a pool has a current and a max size.
>>>
>>> So if erasing speed is say, 250ms, then it would take 6.25 seconds?
>>
>> Only in the very worst case if we have to call 25 times produce_free_peb().
>>
>> Of course we could add a check to return immediately if produce_free_peb()
>> got called a few times in series.
>> But I really would like to wait with such performance tweaks until fastmap
>> is more mature.
> 
> OK, but how about at least adding a comment talking about this unlikely
> scenario?

I'm fine with this. Will send a patch. :-)

Thanks,
//richard


From motobud at gmail.com  Thu Oct  3 23:09:45 2013
From: motobud at gmail.com (Brent Taylor)
Date: Thu, 3 Oct 2013 22:09:45 -0500
Subject: lz4hc compression in UBIFS?
In-Reply-To: <55541379679397@web20h.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
Message-ID: <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>

On Fri, Sep 20, 2013 at 7:16 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
> Hi all,
>
> Are there any plans for adding lz4hc [1] compression support to UBIFS?
>
> Benchmarks are quite impressive, and it looks like lz4hc can achieve better compression ration while providing 3.5x faster decompression. From quick look at UBIFS module sources it looks like adding new compressor supported by crypto API is a matter of a few lines of code in compress.c.
>
> Or are there any known obstacles?
>
> [1] http://code.google.com/p/lz4/
>
> --
> Regards,
> Konstantin
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/

Here is a patch based on linux-3.12-rc3.  I haven't performed any
performance testing UBIFS using lz4hc, but I can mount UBIFS volumes
and haven't seen any problems yet.  The only think I know that isn't
correct about the patch is the description for the Kconfig element for
select lz4hc as a compression option.  I only copied the description
from the lzo description.

diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/compress.c
linux-3.12-rc3/fs/ubifs/compress.c
--- linux-3.12-rc3.orig/fs/ubifs/compress.c     2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/compress.c  2013-07-17 21:57:27.440653860 -0500
@@ -53,6 +53,22 @@
 };
 #endif

+#ifdef CONFIG_UBIFS_FS_LZ4HC
+static DEFINE_MUTEX(lz4hc_mutex);
+
+static struct ubifs_compressor lz4hc_compr = {
+       .compr_type = UBIFS_COMPR_LZ4HC,
+       .comp_mutex = &lz4hc_mutex,
+       .name = "lz4hc",
+       .capi_name = "lz4hc",
+};
+#else
+static struct ubifs_compressor lz4hc_compr = {
+       .compr_type = UBIFS_COMPR_LZ4HC,
+       .name = "lz4hc",
+};
+#endif
+
 #ifdef CONFIG_UBIFS_FS_ZLIB
 static DEFINE_MUTEX(deflate_mutex);
 static DEFINE_MUTEX(inflate_mutex);
@@ -224,10 +240,14 @@
 {
        int err;

-       err = compr_init(&lzo_compr);
+       err = compr_init(&lz4hc_compr);
        if (err)
                return err;

+       err = compr_init(&lzo_compr);
+       if (err)
+               goto out_lz4hc;
+
        err = compr_init(&zlib_compr);
        if (err)
                goto out_lzo;
@@ -237,6 +257,8 @@

 out_lzo:
        compr_exit(&lzo_compr);
+out_lz4hc:
+       compr_exit(&lz4hc_compr);
        return err;
 }

@@ -245,6 +267,7 @@
  */
 void ubifs_compressors_exit(void)
 {
+       compr_exit(&lz4hc_compr);
        compr_exit(&lzo_compr);
        compr_exit(&zlib_compr);
 }
diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/Kconfig
linux-3.12-rc3/fs/ubifs/Kconfig
--- linux-3.12-rc3.orig/fs/ubifs/Kconfig        2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/Kconfig     2013-10-03 21:40:39.098747630 -0500
@@ -29,6 +29,14 @@
           LZO compressor is generally faster than zlib but compresses worse.
           Say 'Y' if unsure.

+config UBIFS_FS_LZ4HC
+       bool "LZ4HC compression support" if UBIFS_FS_ADVANCED_COMPR
+       depends on UBIFS_FS && CRYPTO_LZ4HC
+       default y
+       help
+          LZ4HC compressor is generally faster than zlib but compresses worse.
+          Say 'Y' if unsure.
+
 config UBIFS_FS_ZLIB
        bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR
        depends on UBIFS_FS
diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/super.c
linux-3.12-rc3/fs/ubifs/super.c
--- linux-3.12-rc3.orig/fs/ubifs/super.c        2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/super.c     2013-09-30 23:01:06.899526709 -0500
@@ -1040,6 +1040,8 @@
                                return -ENOMEM;
                        if (!strcmp(name, "none"))
                                c->mount_opts.compr_type = UBIFS_COMPR_NONE;
+                       else if (!strcmp(name, "lz4hc"))
+                               c->mount_opts.compr_type = UBIFS_COMPR_LZ4HC;
                        else if (!strcmp(name, "lzo"))
                                c->mount_opts.compr_type = UBIFS_COMPR_LZO;
                        else if (!strcmp(name, "zlib"))
diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/ubifs-media.h
linux-3.12-rc3/fs/ubifs/ubifs-media.h
--- linux-3.12-rc3.orig/fs/ubifs/ubifs-media.h  2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/ubifs-media.h       2013-07-16
22:56:02.435523610 -0500
@@ -332,12 +332,14 @@
  * UBIFS_COMPR_NONE: no compression
  * UBIFS_COMPR_LZO: LZO compression
  * UBIFS_COMPR_ZLIB: ZLIB compression
+ * UBIFS_COMPR_LZ4HZ: LZ4HZ compression
  * UBIFS_COMPR_TYPES_CNT: count of supported compression types
  */
 enum {
        UBIFS_COMPR_NONE,
        UBIFS_COMPR_LZO,
        UBIFS_COMPR_ZLIB,
+       UBIFS_COMPR_LZ4HC,
        UBIFS_COMPR_TYPES_CNT,
 };

Enjoy,
Brent Taylor


From yousufsait at gmail.com  Fri Oct  4 03:02:18 2013
From: yousufsait at gmail.com (Yousuf Sait)
Date: Fri, 4 Oct 2013 12:32:18 +0530
Subject: ubifs: ubifs tnc found corrupted while trying do_readpage
Message-ID: <CAHXsAqzj+3VEufnU_TjbEMB6yWCBrLT0A3+cYEkSxHsdVcwLkg@mail.gmail.com>

Hi All,

 I am working with ubifs partition of size 380MB on a nand of 512MB.
The volume is on a mtd device of size 400MB.
It was just working great but recently I noticed the following error,

UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): try_read_node: cannot read node type 1 from LEB
953:-1578055608, error -22
UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): do_readpage: cannot read page 1 of inode 2158, error -22
UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): try_read_node: cannot read node type 1 from LEB
953:-1578055608, error -22
UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): do_readpage: cannot read page 1 of inode 2158, error -22

1.The strange thing is that the error vanished when I rebooted the system.
Thus I am ruling out any nand corruption

2.Also there were no nand I/O errors in the log and this is a readonly
partition.

3.The library file was loaded with mmap() and the do_readpage() of ubi code
was exercised for page wise loading.

4.The sequence of the page aceeses from nand was pages 0, 21, 4, 5, 2 and 1,
in which all of those reads succeded expect for page1.

5.While trying to read page1, it tried to read some neg size with neg offset.
There was a sanity check in ubi io code which failed and didn't go till
the nand driver.

6.Surprisingly both the offset and length values that ubi was trying to read
was the same value, -1578055608 (unsigned:  0xA1F0C848).
The actual value was found (from another instance of flashing) to be as
LEB 953:124408, key (2158, data, 1).
That means LEB number was intact while the offset and length got corrupted.

7. We have seen multiple instances of this issue but ubi giving error
for different files. In a different repro, I tried printing all the zbr nodes
with the one which had bad values.
The other ones looks fine expect for the corrupted one (zbr[5] in this case)

[   10.399113] UBIFS: zbr[0] lnum:353 off:26784 len:1641
[   10.399123] UBIFS: zbr[1] lnum:353 off:28432 len:1639
[   10.399133] UBIFS: zbr[2] lnum:353 off:30072 len:1738
[   10.399143] UBIFS: zbr[3] lnum:353 off:31816 len:1621
[   10.399152] UBIFS: zbr[4] lnum:353 off:33440 len:1594
[   10.399163] UBIFS: zbr[5] lnum:353 off:-1445529080 len:-1445529080
[   10.399173] UBIFS: zbr[6] lnum:353 off:36760 len:1788
[   10.399191] UBIFS: zbr[7] lnum:353 off:38552 len:1866
[   10.399209] UBIFS error (pid 87): ubifs_leb_read: reading
-1445529080 bytes from LEB 353:-1445529080 failed, error -22
[   10.399227] UBIFS: ubifs_tnc_locate: ubifs_tnc_read_node failed
key:200004f000000c3f err:-22 safely:1 lnum:off 353:-1445529080

The code I was using is based on K3.1 and I had no luck on reproducing the
issue with latest kernel (3.11).
The repro of the issue is very rare so i am not sure if the newer code fixed
it is there still an issue.

Tree head, with which I reproed the issue,

commit 016f1c54408b1e92e2e8087bfc05ca0a9c258513
Author: Michal Marek <mmarek at suse.cz>
Date:   Thu Aug 11 12:29:46 2011 +0200

UBIFS: not build debug messages with CONFIG_UBIFS_FS_DEBUG disabled ....

Any pointers on how to approach the issue will be useful.

1) Any ideas on what could be wrong here ?
2) Any fix that had solved the issue in the newer kernel ?
3) I can try adding some debug information, any relevant info you would
suggest to add ?

Regards,
Y


From dedekind1 at gmail.com  Fri Oct  4 03:44:44 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Fri, 04 Oct 2013 10:44:44 +0300
Subject: lz4hc compression in UBIFS?
In-Reply-To: <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
Message-ID: <1380872684.18862.19.camel@sauron.fi.intel.com>

On Thu, 2013-10-03 at 22:09 -0500, Brent Taylor wrote:
> +config UBIFS_FS_LZ4HC
> +       bool "LZ4HC compression support" if UBIFS_FS_ADVANCED_COMPR
> +       depends on UBIFS_FS && CRYPTO_LZ4HC
> +       default y
> +       help
> +          LZ4HC compressor is generally faster than zlib but compresses worse.
> +          Say 'Y' if unsure.

I'd say something like:

LZ4HC is generally beats LZO on decompression speed while provides a lot
better compression ratio (comparable to zlib). Compression speed is
generally slower comparing to LZO, but faster comparing to zlib.

Makes sense?

-- 
Best Regards,
Artem Bityutskiy



From annulen at yandex.ru  Fri Oct  4 04:06:02 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Fri, 04 Oct 2013 12:06:02 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
Message-ID: <409951380873962@web7m.yandex.ru>



04.10.2013, 07:09, "Brent Taylor" <motobud at gmail.com>:
> Here is a patch based on linux-3.12-rc3. ?I haven't performed any
> performance testing UBIFS using lz4hc, but I can mount UBIFS volumes
> and haven't seen any problems yet.

Thank you!

Are you planning to implement a patch for mtd-utils (mkfs.ubifs) as well?


> ?The only think I know that isn't
> correct about the patch is the description for the Kconfig element for
> select lz4hc as a compression option. ?I only copied the description
> from the lzo description.
>
> diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/compress.c
> linux-3.12-rc3/fs/ubifs/compress.c
> --- linux-3.12-rc3.orig/fs/ubifs/compress.c ????2013-09-29
> 17:02:38.000000000 -0500
> +++ linux-3.12-rc3/fs/ubifs/compress.c ?2013-07-17 21:57:27.440653860 -0500
> @@ -53,6 +53,22 @@
> ?};
> ?#endif
>
> +#ifdef CONFIG_UBIFS_FS_LZ4HC
> +static DEFINE_MUTEX(lz4hc_mutex);
> +
> +static struct ubifs_compressor lz4hc_compr = {
> + ??????.compr_type = UBIFS_COMPR_LZ4HC,
> + ??????.comp_mutex = &lz4hc_mutex,
> + ??????.name = "lz4hc",
> + ??????.capi_name = "lz4hc",
> +};
> +#else
> +static struct ubifs_compressor lz4hc_compr = {
> + ??????.compr_type = UBIFS_COMPR_LZ4HC,
> + ??????.name = "lz4hc",
> +};
> +#endif
> +
> ?#ifdef CONFIG_UBIFS_FS_ZLIB
> ?static DEFINE_MUTEX(deflate_mutex);
> ?static DEFINE_MUTEX(inflate_mutex);
> @@ -224,10 +240,14 @@
> ?{
> ????????int err;
>
> - ??????err = compr_init(&lzo_compr);
> + ??????err = compr_init(&lz4hc_compr);
> ????????if (err)
> ????????????????return err;
>
> + ??????err = compr_init(&lzo_compr);
> + ??????if (err)
> + ??????????????goto out_lz4hc;
> +
> ????????err = compr_init(&zlib_compr);
> ????????if (err)
> ????????????????goto out_lzo;
> @@ -237,6 +257,8 @@
>
> ?out_lzo:
> ????????compr_exit(&lzo_compr);
> +out_lz4hc:
> + ??????compr_exit(&lz4hc_compr);
> ????????return err;
> ?}
>
> @@ -245,6 +267,7 @@
> ??*/
> ?void ubifs_compressors_exit(void)
> ?{
> + ??????compr_exit(&lz4hc_compr);
> ????????compr_exit(&lzo_compr);
> ????????compr_exit(&zlib_compr);
> ?}
> diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/Kconfig
> linux-3.12-rc3/fs/ubifs/Kconfig
> --- linux-3.12-rc3.orig/fs/ubifs/Kconfig ???????2013-09-29
> 17:02:38.000000000 -0500
> +++ linux-3.12-rc3/fs/ubifs/Kconfig ????2013-10-03 21:40:39.098747630 -0500
> @@ -29,6 +29,14 @@
> ???????????LZO compressor is generally faster than zlib but compresses worse.
> ???????????Say 'Y' if unsure.
>
> +config UBIFS_FS_LZ4HC
> + ??????bool "LZ4HC compression support" if UBIFS_FS_ADVANCED_COMPR
> + ??????depends on UBIFS_FS && CRYPTO_LZ4HC
> + ??????default y
> + ??????help
> + ?????????LZ4HC compressor is generally faster than zlib but compresses worse.
> + ?????????Say 'Y' if unsure.
> +
> ?config UBIFS_FS_ZLIB
> ????????bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR
> ????????depends on UBIFS_FS
> diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/super.c
> linux-3.12-rc3/fs/ubifs/super.c
> --- linux-3.12-rc3.orig/fs/ubifs/super.c ???????2013-09-29
> 17:02:38.000000000 -0500
> +++ linux-3.12-rc3/fs/ubifs/super.c ????2013-09-30 23:01:06.899526709 -0500
> @@ -1040,6 +1040,8 @@
> ????????????????????????????????return -ENOMEM;
> ????????????????????????if (!strcmp(name, "none"))
> ????????????????????????????????c->mount_opts.compr_type = UBIFS_COMPR_NONE;
> + ??????????????????????else if (!strcmp(name, "lz4hc"))
> + ??????????????????????????????c->mount_opts.compr_type = UBIFS_COMPR_LZ4HC;
> ????????????????????????else if (!strcmp(name, "lzo"))
> ????????????????????????????????c->mount_opts.compr_type = UBIFS_COMPR_LZO;
> ????????????????????????else if (!strcmp(name, "zlib"))
> diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/ubifs-media.h
> linux-3.12-rc3/fs/ubifs/ubifs-media.h
> --- linux-3.12-rc3.orig/fs/ubifs/ubifs-media.h ?2013-09-29
> 17:02:38.000000000 -0500
> +++ linux-3.12-rc3/fs/ubifs/ubifs-media.h ??????2013-07-16
> 22:56:02.435523610 -0500
> @@ -332,12 +332,14 @@
> ??* UBIFS_COMPR_NONE: no compression
> ??* UBIFS_COMPR_LZO: LZO compression
> ??* UBIFS_COMPR_ZLIB: ZLIB compression
> + * UBIFS_COMPR_LZ4HZ: LZ4HZ compression
> ??* UBIFS_COMPR_TYPES_CNT: count of supported compression types
> ??*/
> ?enum {
> ????????UBIFS_COMPR_NONE,
> ????????UBIFS_COMPR_LZO,
> ????????UBIFS_COMPR_ZLIB,
> + ??????UBIFS_COMPR_LZ4HC,
> ????????UBIFS_COMPR_TYPES_CNT,
> ?};
>
> Enjoy,
> Brent Taylor

-- 
Regards,
Konstantin


From jagannadh.teki at gmail.com  Fri Oct  4 07:35:47 2013
From: jagannadh.teki at gmail.com (Jagan Teki)
Date: Fri, 4 Oct 2013 17:05:47 +0530
Subject: [U-Boot]: Discussion on Serial Flash Discoverable Parameters
 (SFDP): JESD216A
In-Reply-To: <CAD6G_RTFsNJHEvev28FaV_BMDR=GfPREd=PwZJ_aGZc0k+19HA@mail.gmail.com>
References: <CAD6G_RTFsNJHEvev28FaV_BMDR=GfPREd=PwZJ_aGZc0k+19HA@mail.gmail.com>
Message-ID: <CAD6G_RRMyb62ym3+cKqaxekS6ppXrAVMKnd_Tq4942Mt5=R3Eg@mail.gmail.com>

Added linux-mtd mailing list. and also few developer from winbond.

On Fri, Oct 4, 2013 at 12:21 AM, Jagan Teki <jagannadh.teki at gmail.com> wrote:
> Hi All,
>
> As all we know that the spi_flash is a day-by-day developing hardware
> where each vendor has followed their own standard to get the best to
> come out.
>
> I see SFDP looks like a common standard where most of the vendors were
> following to get the flash parameter information at runtime.
>
> I have couple of questions, added few flash vendors on cc - request
> for all try to give some inputs
> 1. Does all vendors follow this standard at-least from the latest parts?
> 2. Any idea who are not following SFDP
> 3. Does the format of getting data from SFDP is varies from vendor to
> vendor or same?
> 4. Command to get the SFDP is same for all vendors?
> 5. What type of information we can get any list?
>
> Request for your comments, this will really help to shape the
> spi_flash code more dynamic.

-- 
Thanks,
Jagan.
--------
Jagannadha Sutradharudu Teki,
E: jagannadh.teki at gmail.com, P: +91-9676773388
Engineer - System Software hacker
U-boot - SPI Custodian and Zynq APSOC
Ln: http://www.linkedin.com/in/jaganteki


From ezequiel.garcia at free-electrons.com  Fri Oct  4 14:30:37 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri,  4 Oct 2013 15:30:37 -0300
Subject: [PATCH 1/2] mtd: nand: pxa3xx: Move DMA I/O enabling
In-Reply-To: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1380911438-24240-2-git-send-email-ezequiel.garcia@free-electrons.com>

Instead of setting info->dma each time a command is prepared,
we can move it after the DMA buffers are allocated.

This is more clear and it's the proper place to enable this, given
DMA cannot be turned on and off during runtime.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index dd03dfd..a47c67f 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -540,7 +540,6 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 	info->oob_size		= 0;
 	info->use_ecc		= 0;
 	info->use_spare		= 1;
-	info->use_dma		= (use_dma) ? 1 : 0;
 	info->is_ready		= 0;
 	info->retcode		= ERR_NONE;
 	if (info->cs != 0)
@@ -950,6 +949,11 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 		return info->data_dma_ch;
 	}
 
+	/*
+	 * Now that DMA buffers are allocated we turn on
+	 * DMA proper for I/O operations.
+	 */
+	info->use_dma = 1;
 	return 0;
 }
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct  4 14:30:36 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri,  4 Oct 2013 15:30:36 -0300
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
Message-ID: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>

As part of my work to support the NAND controllers in Armada 370/XP SoC
here's a tiny set of patches to replace the currently data buffer allocation
based in a hardcoded buffer size, into a dynamic scheme.

We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
page) and then re-allocate (either with kmalloc or using DMA allocators) using
the detected page size.

The first patch is required to perform the initial NAND operations (READID
and friends) using programmable I/O since the DMA buffers are not ready
at such early stage.

The second patch performs to actual dynamic allocation and it's exactly
the same patch I sent a few weeks ago:

  http://patchwork.ozlabs.org/patch/275982/

Daniel: Can you test these two If they look fine we can add them now,
being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.

Thanks!

Ezequiel Garcia (2):
  mtd: nand: pxa3xx: Move DMA I/O enabling
  mtd: nand: pxa3xx: Allocate data buffer on detected flash size

 drivers/mtd/nand/pxa3xx_nand.c | 51 +++++++++++++++++++++++++++++-------------
 1 file changed, 35 insertions(+), 16 deletions(-)

-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct  4 14:30:38 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri,  4 Oct 2013 15:30:38 -0300
Subject: [PATCH 2/2] mtd: nand: pxa3xx: Allocate data buffer on detected flash
 size
In-Reply-To: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1380911438-24240-3-git-send-email-ezequiel.garcia@free-electrons.com>

This commit replaces the currently hardcoded buffer size, by a
dynamic detection scheme. First a small 256 bytes buffer is allocated
so the device can be detected (using READID and friends commands).

After detection, this buffer is released and a new buffer is allocated
to acommodate the page size plus out-of-band size.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 45 ++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index a47c67f..bfb2b9f 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -39,6 +39,13 @@
 #define NAND_STOP_DELAY		(2 * HZ/50)
 #define PAGE_CHUNK_SIZE		(2048)
 
+/*
+ * Define a buffer size for the initial command that detects the flash device:
+ * STATUS, READID and PARAM. The largest of these is the PARAM command,
+ * needing 256 bytes.
+ */
+#define INIT_BUFFER_SIZE	256
+
 /* registers and bit definitions */
 #define NDCR		(0x00) /* Control register */
 #define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */
@@ -164,6 +171,7 @@ struct pxa3xx_nand_info {
 
 	unsigned int 		buf_start;
 	unsigned int		buf_count;
+	unsigned int		buf_size;
 
 	/* DMA information */
 	int			drcmr_dat;
@@ -911,26 +919,20 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 	return 0;
 }
 
-/* the maximum possible buffer size for large page with OOB data
- * is: 2048 + 64 = 2112 bytes, allocate a page here for both the
- * data buffer and the DMA descriptor
- */
-#define MAX_BUFF_SIZE	PAGE_SIZE
-
 #ifdef ARCH_HAS_DMA
 static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 {
 	struct platform_device *pdev = info->pdev;
-	int data_desc_offset = MAX_BUFF_SIZE - sizeof(struct pxa_dma_desc);
+	int data_desc_offset = info->buf_size - sizeof(struct pxa_dma_desc);
 
 	if (use_dma == 0) {
-		info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
+		info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
 		if (info->data_buff == NULL)
 			return -ENOMEM;
 		return 0;
 	}
 
-	info->data_buff = dma_alloc_coherent(&pdev->dev, MAX_BUFF_SIZE,
+	info->data_buff = dma_alloc_coherent(&pdev->dev, info->buf_size,
 				&info->data_buff_phys, GFP_KERNEL);
 	if (info->data_buff == NULL) {
 		dev_err(&pdev->dev, "failed to allocate dma buffer\n");
@@ -944,7 +946,7 @@ static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 				pxa3xx_nand_data_dma_irq, info);
 	if (info->data_dma_ch < 0) {
 		dev_err(&pdev->dev, "failed to request data dma\n");
-		dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
+		dma_free_coherent(&pdev->dev, info->buf_size,
 				info->data_buff, info->data_buff_phys);
 		return info->data_dma_ch;
 	}
@@ -962,7 +964,7 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
 	struct platform_device *pdev = info->pdev;
 	if (use_dma) {
 		pxa_free_dma(info->data_dma_ch);
-		dma_free_coherent(&pdev->dev, MAX_BUFF_SIZE,
+		dma_free_coherent(&pdev->dev, info->buf_size,
 				  info->data_buff, info->data_buff_phys);
 	} else {
 		kfree(info->data_buff);
@@ -971,7 +973,7 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
 #else
 static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info)
 {
-	info->data_buff = kmalloc(MAX_BUFF_SIZE, GFP_KERNEL);
+	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
 	if (info->data_buff == NULL)
 		return -ENOMEM;
 	return 0;
@@ -1085,7 +1087,16 @@ KEEP_CONFIG:
 	else
 		host->col_addr_cycles = 1;
 
+	/* release the initial buffer */
+	kfree(info->data_buff);
+
+	/* allocate the real data + oob buffer */
+	info->buf_size = mtd->writesize + mtd->oobsize;
+	ret = pxa3xx_nand_init_buff(info);
+	if (ret)
+		return ret;
 	info->oob_buff = info->data_buff + mtd->writesize;
+
 	if ((mtd->size >> chip->page_shift) > 65536)
 		host->row_addr_cycles = 3;
 	else
@@ -1191,9 +1202,13 @@ static int alloc_nand_resource(struct platform_device *pdev)
 	}
 	info->mmio_phys = r->start;
 
-	ret = pxa3xx_nand_init_buff(info);
-	if (ret)
+	/* Allocate a buffer to allow flash detection */
+	info->buf_size = INIT_BUFFER_SIZE;
+	info->data_buff = kmalloc(info->buf_size, GFP_KERNEL);
+	if (info->data_buff == NULL) {
+		ret = -ENOMEM;
 		goto fail_disable_clk;
+	}
 
 	/* initialize all interrupts to be disabled */
 	disable_int(info, NDSR_MASK);
@@ -1211,7 +1226,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
 
 fail_free_buf:
 	free_irq(irq, info);
-	pxa3xx_nand_free_buff(info);
+	kfree(info->data_buff);
 fail_disable_clk:
 	clk_disable_unprepare(info->clk);
 	return ret;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct  4 14:54:55 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 4 Oct 2013 15:54:55 -0300
Subject: [PATCH 03/21] mtd: nand: pxa3xx: Use a completion to signal
 device ready
In-Reply-To: <20131002215628.GW23337@ld-irv-0074.broadcom.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-4-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131002215628.GW23337@ld-irv-0074.broadcom.com>
Message-ID: <20131004185454.GA20476@localhost>

Brian,

First of all: thanks for all your nice feedback.
I'm going through all of it right now, and just started
by this one.

On Wed, Oct 02, 2013 at 02:56:28PM -0700, Brian Norris wrote:
> On Thu, Sep 19, 2013 at 01:01:27PM -0300, Ezequiel Garcia wrote:
> > Apparently, the expected behavior of the waitfunc() NAND chip call
> > is to wait for the device to be READY (this is a standard chip line).
> > However, the current implementation does almost nothing, which opens
> > a possibility to issue a command to a non-ready device.
> > 
> > Fix this by adding a new completion to wait for the ready event to arrive.
> > 
> > Because the "is ready" flag is cleared from the controller status
> > register, it's needed to store that state in the driver, and because the
> > field is accesed from an interruption, the field needs to be of an
> > atomic type.
> 
> Does it really need to be an atomic type? AIUI, you can hand off exclusive
> control to the hardware when you begin a command. So the rest of the driver would be
> inactive when the IRQ handler is setting the ready flag. And similarly,
> the hardware should be inactive (i.e., no interrupts) when you are
> modifying the ready flag in the driver (i.e., in cmdfunc).
> 

Hm... I think that's not the case, and that's exactly why I had to add
an atomic type. See below.

> Or perhaps I'm misunderstanding something.
> 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/nand/pxa3xx_nand.c | 45 +++++++++++++++++++++++++++++-------------
> >  1 file changed, 31 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> > index a8d2ea7..fba91c2 100644
> > --- a/drivers/mtd/nand/pxa3xx_nand.c
> > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> > @@ -35,6 +35,7 @@
> >  
> >  #include <linux/platform_data/mtd-nand-pxa3xx.h>
> >  
> > +#define NAND_DEV_READY_TIMEOUT  50
> >  #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
> >  #define NAND_STOP_DELAY		(2 * HZ/50)
> >  #define PAGE_CHUNK_SIZE		(2048)
> > @@ -167,7 +168,7 @@ struct pxa3xx_nand_info {
> >  	struct clk		*clk;
> >  	void __iomem		*mmio_base;
> >  	unsigned long		mmio_phys;
> > -	struct completion	cmd_complete;
> > +	struct completion	cmd_complete, dev_ready;
> 
> Do you really need two completion structures? Does 'device ready' always
> follow 'command complete', so that you can just use 'device ready' all
> the time? And if so, does it make sense to just use dev_ready?
> 
> >  
> >  	unsigned int 		buf_start;
> >  	unsigned int		buf_count;

The idea here is to handle the following situation. After a command is
completed (which also applies to the 'chunked' page command we want to
support later in the patchset) the controller sets a 'command done' flag
in the ISR.

The interruption handler calls the command done completion which causes
the cmdfunc to finish waiting and exit (or continue executing commands
in the 'chunked' case).

Notice that this does *not* guarantee the controller is ready since the
'ready' flag is independent of the 'command complete' flag and the IRQ can
arrive at any later point.

Let's suppose the cmdfunc() has exited, and the NAND base code is going to
continue the operation. In the PAGEPROG case, the NAND base calls waitfunc()
before continuing the operation.

At that point, we **need** to wait for the 'ready' flag because otherwise
the NAND base could issue another PAGEPROG command, while the controller
is not really ready to receive it.

However, if we enter the waitfunc() we want to read the info->is_ready flag
to check the completion has been initialized and a wait is suitable.
Otherwise, some commands that are not issued (with no wait completion
initialized) will stall at that waitfunc().

While at the waitfunc() the interruption handler might get called for
the 'ready' flag and so the info->is_ready variable gets access from two
different execution contexts.

Given the above behavior, I thought the only way of dealing with this
was to add a new completion and use atomic type for the is_ready flag.

Is the above clear? Do you think the implementation is correct for the
behavior?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Fri Oct  4 15:42:04 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 4 Oct 2013 16:42:04 -0300
Subject: [PATCH 00/21] Armada 370/XP NAND support
In-Reply-To: <20131003000253.GX23337@ld-irv-0074.broadcom.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20130926195615.GK23337@ld-irv-0074.broadcom.com>
 <20130930122428.GA2417@localhost>
 <20131003000253.GX23337@ld-irv-0074.broadcom.com>
Message-ID: <20131004194203.GB20476@localhost>

On Wed, Oct 02, 2013 at 05:02:53PM -0700, Brian Norris wrote:
> On Mon, Sep 30, 2013 at 09:24:29AM -0300, Ezequiel Garcia wrote:
> > On Thu, Sep 26, 2013 at 12:56:15PM -0700, Brian Norris wrote:
> > > On Thu, Sep 19, 2013 at 01:01:24PM -0300, Ezequiel Garcia wrote:
> > > > * Page layout
> > > > 
> > > > The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
> > > > larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
> > > > chunked transfers.
> > > > 
> > > > For instance, if we choose a 2048 data chunk and BCH ECC we will have
> > > > to use this layout in the pages:
> > > > 
> > > >   ------------------------------------------------------------------------------
> > > >   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
> > > >   ------------------------------------------------------------------------------
> > > > 
> > > > The last remaining area is unusable (i.e. wasted).
> > > 
> > > Why is it wasted? With a 2176B buffer, you can fit more than 2048+32+30.
> > > Are you simplifying things to support only NAND geometries like the
> > > tradiditional large page 2KB+64? (If so, what happens with 4KB pages
> > > that need higher level of ECC than can fit in 64 x 2 = 128B?) And in the
> > > 2KB+64 case, why is the 64-32-30=2B wasted?
> > > 
> > 
> > Hm... the wasted bytes are due to an 8-byte alignment controller requirement on the
> > data buffer. However, you're right: in a flash with a page of 4KB+224B (e.g.) you
> > should be able to access at least some of the remaining OOB area.
> 
> Alignment requirement for the start of the buffer, length of the buffer,
> or both?
> 

The specification requires the length of a transaction (amount of data in the
data buffer) to be aligned to 8 bytes.

> > Notice OOB handling is still a bit confusing in this driver.
> 
> Yes.
> 
> > > > To match this, my current (already working!) implementation acts like
> > > > a layout "impedance matcher" to produce in an internal driver's buffer
> > > 
> > > Maybe I'm in the wrong field, but I'm not sure how an impedance matcher
> > > applies here.
> > > 
> > > > this layout:
> > > > 
> > > >   ------------------------------------------
> > > >   |     4096B data     |     64B spare     |
> > > >   ------------------------------------------
> > > 
> > > What is this "internal buffer"? (I'll read through your patches in a bit
> > > and find out, perhaps?) Just the raw data + spare that you are ready to
> > > read/write? Are you dropping the ECC from this buffer? Doesn't it need
> > > to be returned to the callee (when the 'oob_required' flag is true)?
> > > 
> > 
> > Yes, the driver's internal buffer has the raw data + OOB that has
> > been read from the controller after a read operation, or that's
> > ready to be written to the flash before a program operation.
> > 
> > That said, if the command issued was READOOB then the OOB is read fully:
> > spare and ECC code and the buffer is filled like this:
> > 
> >   ----------------------------------------------------------------------------------------------
> >   |     4096B data     |  32B spare  |  30B ECC*  | 2x 0xff |  32B spare  |  30B ECC  | 2x 0xff |
> >   ----------------------------------------------------------------------------------------------
> > 
> > (*) We need to add two bytes (0xff) to align the 30B ECC read.
> > 
> > I was expecting to handle the above layout properly using this nand_ecclayout
> > structure:
> > 
> > static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
> >         .eccbytes = 64,
> >         .eccpos = {
> >                 32,  33,  34,  35,  36,  37,  38,  39,
> >                 40,  41,  42,  43,  44,  45,  46,  47,
> >                 48,  49,  50,  51,  52,  53,  54,  55,
> >                 56,  57,  58,  59,  60,  61,  62,  63,
> >                 96,  97,  98,  99,  100, 101, 102, 103,
> >                 104, 105, 106, 107, 108, 109, 110, 111,
> >                 112, 113, 114, 115, 116, 117, 118, 119,
> >                 120, 121, 122, 123, 124, 125, 126, 127},
> >         /* Bootrom looks in bytes 0 & 5 for bad blocks */
> >         .oobfree = { {1, 4}, {6, 26}, { 64, 32} }
> > };
> > 
> > However, I must be doing something wrong since currently the mtd_oobtest fails
> > at some point and I need to investigate the issue further.
> > 
> > > > In order to achieve reading (for instance), we issue several READ0 commands
> > > > (with some additional controller-specific magic) and read two chunks of 2080B
> > > > (2048 data + 64 spare) each.
> > > 
> > > The math is a little inconsistent here and elsewhere. Do you mean two
> > > chunks of 2080B (2048 data + 32 spare)?
> > > 
> > 
> > Yes. It should be: 2048B data + 32B spare.
> > 
> > > > The driver accomodates this data to expose the NAND base a contiguous 4160B buffer
> > > > (4096 data + 64 spare).
> > > 
> > > This math matches up right, if it's double the 2KB+32 instead of double
> > > 2KB+64.
> > > 
> > 
> > Yup.
> > 
> > > > * ECC
> > > > 
> > > > The controller has built-in hardware ECC capabilities. In addition it is completely
> > > > configurable, and we can choose between Hamming and BCH ECC. If we choose BCH ECC
> > > > then the ECC code will be calculated for each transfered chunk and expected to be
> > > > located (when reading/programming) at specific locations.
> > > 
> > > At "specific locations", but always within the 30B region that you've
> > > been mapping out?
> > > 
> > 
> > By 'specific location' I mean after the 32B spare area.
> > 
> > > > So, repeating the above scheme, a 2048B data chunk will be followed by 32B spare,
> > > > and then the ECC controller will read/write the ECC code (30B in this case):
> > > > 
> > > >   ------------------------------------
> > > >   | 2048B data | 32B spare | 30B ECC |
> > > >   ------------------------------------
> > > 
> > > Is ECC always 30B? Or is this just the maximum size, so you always
> > > reserve 30B?
> > > 
> > 
> > In the BCH case, yes: it's always 30B.
> 
> So by "BCH" you actually are referring to BCH-4? Are there any other BCH
> modes supported? Or do you expect any future revisions to expand on the
> BCH options available?
> 

Mmm.. ECC BCH is always 30 bytes long, but this doesn't mean it's BCH-4.
See below.

> > AFAIK, the ECC works like this. When programming a page, you can
> > actually instruct the controller to transfer an arbitrary amount of bytes.
> > 
> > (Details: you do this by adding NDCB0_LEN_OVRD to the command buffer 0,
> > and setting the i/o length at buffer 3).
> > 
> > The ECC code will be written after the transfered bytes. So, when
> > programming a page we configure the length to be 2048B + 32B and get
> > the ECC after it.
> > 
> > Equally, we can read an arbitrary length. and the ECC code is expected
> > to be in the area immediate the read area.
> > 
> > Notice that this means you can control the ECC strength: since the ECC
> > is always 30B, and it's calculated on the transfered chunk you can
> > configure the controller to transfer the page in 1024B chunks and get a
> > 30B ECC for each of this chunk, thus doubling the ECC strength.
> 
> This is a little odd. Your ECC HW is not parameterized by ECC strength,
> but instead by ECC sector size? I think I have some comments for patch
> 5, relevant to this topic.
> 

Indeed. When ECC engine in the controller is set to do BCH, it always
store a 30-byte ECC code. This 30-byte code is calculated on the
transfered chunk, and since the chunk size is configurable we can
effectively configure the ECC strength.

The specification says the ECC BCH engine can correct up to 16-bits,
which means: if the chunk is 2048 bytes you get BCH-4, and if the chunk
is set to be 1024 bytes, you get BCH-8.

Only the former has been implemented in this v1.

Is this clearer now? Don't hesitate in asking more questions as it helps
me fill my own understanding gaps :-)
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Fri Oct  4 15:49:24 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 4 Oct 2013 16:49:24 -0300
Subject: [PATCH 05/21] mtd: nand: pxa3xx: Add driver-specific ECC BCH
 support
In-Reply-To: <20131003002440.GY23337@ld-irv-0074.broadcom.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-6-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131003002440.GY23337@ld-irv-0074.broadcom.com>
Message-ID: <20131004194923.GC20476@localhost>

On Wed, Oct 02, 2013 at 05:24:40PM -0700, Brian Norris wrote:
> On Thu, Sep 19, 2013 at 01:01:29PM -0300, Ezequiel Garcia wrote:
> > This commit adds the BCH ECC support available in NFCv2 controller.
> > Depending on the detected required strength the respective ECC layout
> > is selected.
> > 
> > This commit adds an empty ECC layout, since support to access large
> > pages is first required. Once that support is added, a proper ECC
> > layout will be added as well.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/nand/pxa3xx_nand.c | 53 ++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 46 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> > index a0dabe6..86c343e 100644
> > --- a/drivers/mtd/nand/pxa3xx_nand.c
> > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> 
> ...
> 
> > @@ -1117,10 +1133,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
> >  	pxa3xx_flash_ids[1].name = NULL;
> >  	def = pxa3xx_flash_ids;
> >  KEEP_CONFIG:
> > -	chip->ecc.mode = NAND_ECC_HW;
> > -	chip->ecc.size = host->page_size;
> > -	chip->ecc.strength = 1;
> > -
> >  	if (info->reg_ndcr & NDCR_DWIDTH_M)
> >  		chip->options |= NAND_BUSWIDTH_16;
> >  
> > @@ -1130,8 +1142,35 @@ KEEP_CONFIG:
> >  		chip->bbt_options |= NAND_BBT_USE_FLASH;
> >  	}
> >  
> > +	/* Device detection must be done with ECC disabled */
> > +	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
> > +		nand_writel(info, NDECCCTRL, 0x0);
> > +
> >  	if (nand_scan_ident(mtd, 1, def))
> >  		return -ENODEV;
> > +
> > +	/* 1-step ECC over the entire detected page size */
> > +	chip->ecc.mode = NAND_ECC_HW;
> > +	chip->ecc.size = mtd->writesize;
> 
> Does the ECC really only work in one step? IOW, do you only correct
> 1-bit for the entire page? That is under-spec'd for most NAND (they need
> 1-bit/512-byte, or 4-bit/512-byte). This ecc.size should actually
> reflect the correction region (typically 512B or 1024B), and even if
> your buffer layout makes a step every 2KB (or 4KB or whatever), the ECC
> step size *should* be smaller than that.
> 
> Or maybe I'm wrong, and you're actually using a weak 4-bit correction
> over 2048 bytes.
> 

I must admit I'm a bit confused by this ECC step concept. Having
described the ECC engine in the cover-letter, what do you think
the right choice should be?

IMO, given the ECC engine works on the entire FIFO (actually it works
on the transfered chunk) it's a 1-step ECC.

On the other side, a multiple step ECC, i.e. chip->ecc.size != mtd->writesize
makes the NAND base calls the subpage() function and the driver crashes
horribly when using UBIFS.

I'm not sure why subpage should be called in that case, given we don't
support that.

> > +
> > +	/*
> > +	 * Armada370 variant supports BCH, which provides 4-bit strength
> > +	 * and needs to be supported in a special way.
> > +	 */
> > +	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
> 
> Might there be other variants eventually that support BCH? Perhaps you
> want to separate the property of "can use BCH" from "will use BCH"?
> 

Yeah, probably. And maybe setting the BCH from the DT? The problem here
is that because of the ECC choice being intimately related to the OOB
location, this means the ECC choice is intimately related to the bad
block markers.

IOW, the user can't really choose among ECC.

I guess this means the ECC choice is some sort of a hardware description
and rightfully belongs to the DT. Right?

> > +	    chip->ecc_strength_ds == 4) {
> 
> Do you use BCH-4 only for chips that require exactly 4-bit correction?
> Is there ever a need to "overclock" the ECC, and choose BCH-4 for chips
> that only require 1-bit correction? Can the bootloader ever make a
> choice different from yours here?
> 
> What about NAND that don't support the ecc_strength_ds field yet?
> Remember, this is only filled for ONFI NAND and a few NAND that are in
> the full-ID table.
> 
> > +	        chip->ecc.layout = &ecc_layout_4KB_bch4bit;
> 
> This seems to have an implicit page size assumption. In your case, it
> seems like this layout should be chosen based on the page size + OOB
> size, at least.
> 
> > +		chip->ecc.strength = chip->ecc_strength_ds;
> > +		info->ecc_bch = 1;
> > +	} else if (mtd->writesize <= 2048) {
> > +		/*
> > +		 * This is the default ECC Hamming 1-bit strength case,
> > +		 * which works for page sizes of 512 and 2048 bytes.
> > +		 * The ECC layout will be automatically configured.
> > +		 */
> > +		chip->ecc.strength = 1;
> > +	}
> 
> What about the 'else' case? What happens with >2KB page NAND on
> non-Armada370 systems? What happens if a NAND needs >4-bit correction?
> Perhaps you could include a warning/error? I don't know the flexibility
> of NAND types you'll find on an Armada board; maybe they're all
> ONFI-compliant?
> 

Yeah, this 'ifs' could be fixed to better support other cases.

I'll try to rework that.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Fri Oct  4 15:49:42 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:42 +0530
Subject: [PATCH v7 0/6] mtd:nand:omap2: clean-up of supported ECC schemes
Message-ID: <1380916188-24206-1-git-send-email-pekon@ti.com>


*Changes v6 -> v7*
[PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks of Brain Norris
[PATCH 2/6] incorporated feedbacks from DT maintainers
[PATCH 3/6] patch cleaning and incorporated feedbacks from Brain Norris
[PATCH 4/6] rebasing changes and cleanup
[PATCH 5/6] updated omap3430-sdp.dts
[PATCH 6/6] <NEW> updated for devm_xx


*Changes v5 -> v6*
[PATCH 1/4]: 
	- updated DT binding for gpmc-nand based on 'Olof Johansson's feedbacks
	http://lists.infradead.org/pipermail/linux-mtd/2013-August/048394.html
	- detection of ELM device via ti,elm-id DT node, moved to gpmc.c driver
[PATCH 2/4]
	- removed: support for following obselete ECC schemes
	OMAP_ECC_HAMMING_CODE_DEFAULT (S/W based 1-bit Hamming ECC)
	OMAP_ECC_HAMMING_CODE_HW_ROMCODE (H/W based 1-bit Hamming ECC scheme)
	- updated: using omap_oobinfo as chip->ecc.layout for all ecc-schemes
	- clean: error messages
[PATCH 3/4] cleaned to include changes for OMAP_ECC_BCH8_CODE_HW only
[PATCH 4/4] updated to include DT property changes


*Changes v4 -> v5*
- Rebased to linux-next 
IMPORTANT: Need to revert commit fb1585b, [PATCH 2/4] part of previous version
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047441.html

- Swapped PATCH-1 & PATCH-2 to maintain bisectibility & compilation dependency
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047461.html

- PATCH-2: re-ordered call to is_elm_present() for later updates ELM driver
	- dropped changes in include/linux/platform_data/elm.h (not needed)
- PATCH-3: re-ordered call to is_elm_present() for later updates ELM driver
- Re-formated patch description (replaced tabs with white-spaces)


*Changes v3 -> v4*
(Resent with CC: devicetree-discuss at lists.ozlabs.org)
- [Patch 1/3] removed MTD_NAND_OMAP_BCH8 & MTD_NAND_OMAP_BCH4 from nand/Kconfig
	ECC scheme selectable via nand DT (nand-ecc-opt).
- [*] rebased for l2-mtd.git


*Changes v2 -> v3*
(Resent with Author Name fixed)
- PATCH-1: re-arranged code to remove redundancy, added NAND_BUSWIDTH_AUTO
- PATCH-2: updated nand-ecc-opt DT mapping and Documentation
- PATCH-3: code-cleaning + changes to match PATCH-1
- PATCH-4 <DROPPED> update DT attribute for ti,nand-ecc-opt 
	- received feedback to keep DT mapping independent of linuxism
- PATCH-4:<NEW> : ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
	- independent patch for AM335x-evm.dts update based on PATCH-2


*Changes v1 -> v2*
	added 	[PATCH 3/4] and [PATCH 4/4]


After this patch series, omap2-nand driver will supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+

To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine


Pekon Gupta (6):
  mtd: nand: omap: combine different flavours of 1-bit hamming ecc
    schemes
  ARM: OMAP2+: cleaned-up DT support of various ECC schemes
  mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
    device_probe
  mtd:nand:omap2: updated support for BCH4 ECC scheme
  ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
  mtd: nand: omap: updated devm_xx for all resource allocation and free
    calls

 .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
 arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
 arch/arm/mach-omap2/board-flash.c                  |   2 +-
 arch/arm/mach-omap2/gpmc.c                         |  49 +-
 drivers/mtd/nand/Kconfig                           |  30 +-
 drivers/mtd/nand/omap2.c                           | 569 ++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
 8 files changed, 335 insertions(+), 354 deletions(-)

-- 
1.8.1



From pekon at ti.com  Fri Oct  4 15:49:43 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:43 +0530
Subject: [PATCH v7 1/6] mtd: nand: omap: combine different flavours of 1-bit
 hamming ecc schemes
In-Reply-To: <1380916188-24206-1-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
Message-ID: <1380916188-24206-2-git-send-email-pekon@ti.com>

OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
ecc-scheme, like:
- OMAP_ECC_HAMMING_CODE_DEFAULT
	1-bit hamming ecc code using software library
- OMAP_ECC_HAMMING_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine
- OMAP_ECC_HAMMING_CODE_HW_ROMCODE
	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
	to ROM code.

This patch combines above multiple ecc-schemes into single implementation:
- OMAP_ECC_HAM1_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
	ecc-layout.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
 arch/arm/mach-omap2/board-flash.c                   | 2 +-
 arch/arm/mach-omap2/gpmc.c                          | 4 +---
 drivers/mtd/nand/omap2.c                            | 9 +++------
 include/linux/platform_data/mtd-nand-omap2.h        | 6 +-----
 5 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index df338cb..25ee232 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -22,10 +22,10 @@ Optional properties:
 				width of 8 is assumed.
 
  - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-
-		"sw"		Software method (default)
-		"hw"		Hardware method
-		"hw-romcode"	gpmc hamming mode method & romcode layout
+		"sw"		<deprecated> use "ham1" instead
+		"hw"		<deprecated> use "ham1" instead
+		"hw-romcode"	<deprecated> use "ham1" instead
+		"ham1"		1-bit Hamming ecc code
 		"bch4"		4-bit BCH ecc code
 		"bch8"		8-bit BCH ecc code
 
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index fc20a61..ac82512 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
 
-	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
 	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/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 9f4795a..1c45b72 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1342,9 +1342,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 #ifdef CONFIG_MTD_NAND
 
 static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
-	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
-	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
+	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
 	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
 	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
 };
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..8d521aa 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1993,10 +1993,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
-		info->nand.ecc.mode = NAND_ECC_SOFT;
-	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
-		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 		info->nand.ecc.bytes            = 3;
 		info->nand.ecc.size             = 512;
 		info->nand.ecc.strength         = 1;
@@ -2025,7 +2022,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
 		if (info->nand.options & NAND_BUSWIDTH_16)
 			offset = 2;
@@ -2033,7 +2030,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			offset = 1;
 			info->nand.badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16);
+		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 6bf9ef4..cb5a54a 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,11 +23,7 @@ enum nand_io {
 };
 
 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_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
 	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
 	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
 };
-- 
1.8.1



From pekon at ti.com  Fri Oct  4 15:49:44 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:44 +0530
Subject: [PATCH v7 2/6] ARM: OMAP2+: cleaned-up DT support of various ECC
 schemes
In-Reply-To: <1380916188-24206-1-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
Message-ID: <1380916188-24206-3-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in following
different flavours, depending on in-build Hardware engines supported by SoC.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+
To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine

DT binding updates in this patch are:
- ti,elm-id: replaces elm_id
- ti,nand-ecc-opts: supported values ham1, bch4, and bch8
	selection of h/w or s/w implementation depends on ti,elm-id

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
 arch/arm/mach-omap2/gpmc.c                         | 47 ++++++++++++++++------
 include/linux/platform_data/mtd-nand-omap2.h       | 14 +++++--
 3 files changed, 52 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 25ee232..7785666 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -36,8 +36,12 @@ Optional properties:
 		"prefetch-dma"		Prefetch enabled sDMA mode
 		"prefetch-irq"		Prefetch enabled irq mode
 
- - elm_id:	Specifies elm device node. This is required to support BCH
- 		error correction using ELM module.
+ - elm_id:	<deprecated> use "ti,elm-id" instead
+ - ti,elm-id:	Specifies pHandle of the ELM devicetree node.
+		ELM is an on-chip hardware engine on TI SoC which is used for
+		locating ECC errors for BCHx algorithms. SoC devices which have
+		ELM hardware engines should specify this device node in .dtsi
+		Using ELM for ECC error correction frees some CPU cycles.
 
 For inline partiton table parsing (optional):
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 1c45b72..5a607fa 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1341,12 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 
 #ifdef CONFIG_MTD_NAND
 
-static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
-	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
-	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
-};
-
 static const char * const nand_xfer_types[] = {
 	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
 	[NAND_OMAP_POLLED]			= "polled",
@@ -1361,6 +1355,8 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 	const char *s;
 	struct gpmc_timings gpmc_t;
 	struct omap_nand_platform_data *gpmc_nand_data;
+	const __be32 *phandle;
+	int lenp;
 
 	if (of_property_read_u32(child, "reg", &val) < 0) {
 		dev_err(&pdev->dev, "%s has no 'reg' property\n",
@@ -1376,12 +1372,39 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 	gpmc_nand_data->cs = val;
 	gpmc_nand_data->of_node = child;
 
-	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-			if (!strcasecmp(s, nand_ecc_opts[val])) {
-				gpmc_nand_data->ecc_opt = val;
-				break;
-			}
+	/* Detect availability of ELM module */
+	phandle = of_get_property(child, "ti,elm-id", &lenp);
+	if ((phandle == NULL) || (lenp != sizeof(void *))) {
+		pr_warn("%s: ti,elm-id property not found\n", __func__);
+		gpmc_nand_data->elm_of_node = NULL;
+	} else {
+		gpmc_nand_data->elm_of_node =
+				of_find_node_by_phandle(be32_to_cpup(phandle));
+	}
+	/* select NAND ecc-opt */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!strcmp(s, "ham1"))
+		gpmc_nand_data->ecc_opt =
+				OMAP_ECC_HAM1_CODE_HW;
+	else if (!strcmp(s, "bch4"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	else if (!strcmp(s, "bch8"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	else
+		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
 
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
 		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index cb5a54a..4da5bfa 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,9 +23,16 @@ enum nand_io {
 };
 
 enum omap_ecc {
-	OMAP_ECC_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
-	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
-	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
+	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_HAM1_CODE_HW = 0,
+	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH4_CODE_HW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH8_CODE_HW,
 };
 
 struct gpmc_nand_regs {
@@ -59,5 +66,6 @@ struct omap_nand_platform_data {
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
+	struct device_node	*elm_of_node;
 };
 #endif
-- 
1.8.1



From pekon at ti.com  Fri Oct  4 15:49:45 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:45 +0530
Subject: [PATCH v7 3/6] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <1380916188-24206-1-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
Message-ID: <1380916188-24206-4-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in following
different flavours, depending on in-build Hardware engines supported by SoC.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+
To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        enables S/W based BCH ECC algorithm
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       enables H/W based BCH ECC algorithm

This patch
- removes OMAP_ECC_HAMMING_CODE_DEFAULT and OMAP_ECC_HAMMING_CODE_HW_ROMCODE
- separates the configurations for other ECC schemes
- fixes dependency issues based on Kconfig options
- updates ELM device detection in is_elm_present()
- cleans redundant code

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 450 +++++++++++++++++++++++------------------------
 1 file changed, 220 insertions(+), 230 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8d521aa..fb96251 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,8 +25,10 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 #include <linux/bch.h>
+#endif
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/platform_data/elm.h>
 #endif
 
@@ -141,6 +143,9 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define BADBLOCK_MARKER_LENGTH		2
+#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
+
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 	0xac, 0x6b, 0xff, 0x99, 0x7b};
@@ -182,14 +187,11 @@ struct omap_nand_info {
 	u_char				*buf;
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-	struct bch_control             *bch;
-	struct nand_ecclayout           ecclayout;
+	/* fields specific for BCHx_HW ECC scheme */
+	struct bch_control              *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
-#endif
 };
 
 /**
@@ -1058,8 +1060,7 @@ static int omap_dev_ready(struct mtd_info *mtd)
 	}
 }
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
  * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
  * @mtd: MTD device structure
@@ -1140,7 +1141,9 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	/* Clear ecc and enable bits */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
+#endif
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
  * @mtd: MTD device structure
@@ -1225,7 +1228,9 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 
 	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1517,7 +1522,9 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
+#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_correct_data_bch - Decode received data and correct errors
  * @mtd: MTD device structure
@@ -1549,7 +1556,9 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
 	}
 	return count;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1637,197 +1646,68 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
+ * is_elm_present - checks for presence of ELM module by scanning DT nodes
+ * @omap_nand_info: NAND device structure containing platform data
+ * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16
  */
-static void omap3_free_bch(struct mtd_info *mtd)
+static int is_elm_present(struct omap_nand_info *info,
+			struct device_node *elm_node, enum bch_ecc bch_type)
 {
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-/**
- * omap3_init_bch - Initialize BCH ECC
- * @mtd: MTD device structure
- * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW)
- */
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	int max_errors;
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-#ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = BCH8_MAX_ERROR;
-#else
-	const int hw_errors = BCH4_MAX_ERROR;
-#endif
-	enum bch_ecc bch_type;
-	const __be32 *parp;
-	int lenp;
-	struct device_node *elm_node;
-
-	info->bch = NULL;
-
-	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);
-		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 = max_errors;
-
-	if (hw_errors == BCH8_MAX_ERROR)
-		bch_type = BCH8_ECC;
-	else
-		bch_type = BCH4_ECC;
-
-	/* Detect availability of ELM module */
-	parp = of_get_property(info->of_node, "elm_id", &lenp);
-	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
-		pr_err("Missing elm_id property, fall back to Software BCH\n");
-		info->is_elm_used = false;
-	} else {
-		struct platform_device *pdev;
-
-		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
-		pdev = of_find_device_by_node(elm_node);
-		info->elm_dev = &pdev->dev;
-
-		if (elm_config(info->elm_dev, bch_type) == 0)
-			info->is_elm_used = true;
+	struct platform_device *pdev;
+	info->is_elm_used = false;
+	/* check whether elm-id is passed via DT */
+	if (!elm_node) {
+		pr_err("nand: error: ELM DT node not found\n");
+		return -ENODEV;
 	}
-
-	if (info->is_elm_used && (mtd->writesize <= 4096)) {
-
-		if (hw_errors == BCH8_MAX_ERROR)
-			info->nand.ecc.bytes = BCH8_SIZE;
-		else
-			info->nand.ecc.bytes = BCH4_SIZE;
-
-		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;
-	} else {
-		/*
-		 * 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;
-		}
+	pdev = of_find_device_by_node(elm_node);
+	/* check whether ELM device is registered */
+	if (!pdev) {
+		pr_err("nand: error: ELM device not found\n");
+		return -ENODEV;
 	}
-
-	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
+	/* ELM module available, now configure it */
+	info->elm_dev = &pdev->dev;
+	if (elm_config(info->elm_dev, bch_type))
+		return -ENODEV;
+	info->is_elm_used = true;
 	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
- * omap3_init_bch_tail - Build an oob layout for BCH ECC correction.
+ * omap3_free_bch - Release BCH ecc resources
  * @mtd: MTD device structure
  */
-static int omap3_init_bch_tail(struct mtd_info *mtd)
+static void omap3_free_bch(struct mtd_info *mtd)
 {
-	int i, steps, offset;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-	struct nand_ecclayout *layout = &info->ecclayout;
-
-	/* build oob layout */
-	steps = mtd->writesize/info->nand.ecc.size;
-	layout->eccbytes = steps*info->nand.ecc.bytes;
-
-	/* do not bother creating special oob layouts for small page devices */
-	if (mtd->oobsize < 64) {
-		pr_err("BCH ecc is not supported on small page devices\n");
-		goto fail;
-	}
-
-	/* reserve 2 bytes for bad block marker */
-	if (layout->eccbytes+2 > mtd->oobsize) {
-		pr_err("no oob layout available for oobsize %d eccbytes %u\n",
-		       mtd->oobsize, layout->eccbytes);
-		goto fail;
+	if (info->bch) {
+		free_bch(info->bch);
+		info->bch = NULL;
 	}
-
-	/* 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] = 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].length = mtd->oobsize-2-layout->eccbytes;
-	info->nand.ecc.layout = layout;
-
-	if (!(info->nand.options & NAND_BUSWIDTH_16))
-		info->nand.badblock_pattern = &bb_descrip_flashbased;
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
 
 #else
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n");
-	return -1;
-}
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	return -1;
-}
+
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
 	struct omap_nand_platform_data	*pdata;
+	struct mtd_info			*mtd;
+	struct nand_chip		*nand_chip;
+	struct nand_ecclayout		*ecclayout;
 	int				err;
-	int				i, offset;
-	dma_cap_mask_t mask;
-	unsigned sig;
+	int				i;
+	dma_cap_mask_t			mask;
+	unsigned			sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
 
@@ -1846,20 +1726,18 @@ static int omap_nand_probe(struct platform_device *pdev)
 	spin_lock_init(&info->controller.lock);
 	init_waitqueue_head(&info->controller.wq);
 
-	info->pdev = pdev;
-
+	mtd			= &info->mtd;
+	mtd->name		= dev_name(&pdev->dev);
+	mtd->owner		= THIS_MODULE;
+	mtd->priv		= &info->nand;
+	nand_chip		= &info->nand;
+	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
+	info->bch		= NULL;
 
-	info->mtd.priv		= &info->nand;
-	info->mtd.name		= dev_name(&pdev->dev);
-	info->mtd.owner		= THIS_MODULE;
-
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 	info->of_node		= pdata->of_node;
-#endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
@@ -1903,6 +1781,30 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->nand.chip_delay = 50;
 	}
 
+	/* scan NAND device conncted to controller */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		err = -ENXIO;
+		goto out_release_mem_region;
+	}
+	pr_info("%s: detected %s NAND flash\n", DRIVER_NAME,
+			(nand_chip->options & NAND_BUSWIDTH_16) ? "x16" : "x8");
+	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
+			(pdata->devsize & NAND_BUSWIDTH_16)) {
+		pr_err("%s: but incorrectly configured as %s", DRIVER_NAME,
+			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* check for small page devices */
+	if ((mtd->oobsize < 64) &&
+		(pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
+		pr_err("small page devices are not supported\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* populate read & write API based on xfer_type selected */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		info->nand.read_buf   = omap_read_buf_pref;
@@ -1992,61 +1894,148 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-		info->nand.ecc.bytes            = 3;
-		info->nand.ecc.size             = 512;
-		info->nand.ecc.strength         = 1;
-		info->nand.ecc.calculate        = omap_calculate_ecc;
-		info->nand.ecc.hwctl            = omap_enable_hwecc;
-		info->nand.ecc.correct          = omap_correct_data;
-		info->nand.ecc.mode             = NAND_ECC_HW;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(&info->mtd, pdata->ecc_opt);
-		if (err) {
+	/* populate MTD interface based on ECC scheme */
+	nand_chip->ecc.layout	= &omap_oobinfo;
+	ecclayout		= &omap_oobinfo;
+	switch (pdata->ecc_opt) {
+	case OMAP_ECC_HAM1_CODE_HW:
+		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
+		nand_chip->ecc.mode             = NAND_ECC_HW;
+		nand_chip->ecc.bytes            = 3;
+		nand_chip->ecc.size             = 512;
+		nand_chip->ecc.strength         = 1;
+		nand_chip->ecc.calculate        = omap_calculate_ecc;
+		nand_chip->ecc.hwctl            = omap_enable_hwecc;
+		nand_chip->ecc.correct          = omap_correct_data;
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		if (nand_chip->options & NAND_BUSWIDTH_16)
+			ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
+		else
+			ecclayout->eccpos[0]	= 1;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		break;
+
+	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 7;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
-			goto out_release_mem_region;
 		}
-	}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
-			err = -ENXIO;
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 13;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
+			err = -EINVAL;
 			goto out_release_mem_region;
 		}
-	}
-
-	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
 
-		if (info->nand.options & NAND_BUSWIDTH_16)
-			offset = 2;
-		else {
-			offset = 1;
-			info->nand.badblock_pattern = &bb_descrip_flashbased;
-		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
-		for (i = 0; i < omap_oobinfo.eccbytes; i++)
-			omap_oobinfo.eccpos[i] = i+offset;
-
-		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = info->mtd.oobsize -
-					(offset + omap_oobinfo.eccbytes);
-
-		info->nand.ecc.layout = &omap_oobinfo;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(&info->mtd);
-		if (err) {
-			err = -EINVAL;
+	case OMAP_ECC_BCH8_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 13 + 1;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
 			goto out_release_mem_region;
 		}
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	default:
+		pr_err("nand: error: invalid or unsupported ECC scheme\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* populate remaining info for custom ecc layout */
+	pr_info("%s: using custom ecc layout\n", DRIVER_NAME);
+	ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH
+						- ecclayout->eccbytes;
+	if (!(nand_chip->options & NAND_BUSWIDTH_16))
+		nand_chip->badblock_pattern = &bb_descrip_flashbased;
+	for (i = 1; i < ecclayout->eccbytes; i++)
+		ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
+	/* check if NAND OOBSIZE meets ECC scheme requirement */
+	if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
+		pr_err("not enough OOB bytes required = %d, available=%d\n",
+			ecclayout->eccbytes, mtd->oobsize);
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* second phase scan */
@@ -2072,6 +2061,7 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
+	omap3_free_bch(&info->mtd);
 	kfree(info);
 
 	return err;
-- 
1.8.1



From pekon at ti.com  Fri Oct  4 15:49:46 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:46 +0530
Subject: [PATCH v7 4/6] mtd:nand:omap2: updated support for BCH4 ECC scheme
In-Reply-To: <1380916188-24206-1-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
Message-ID: <1380916188-24206-5-git-send-email-pekon@ti.com>

This patch adds following two flavours of BCH4 ECC scheme in omap2-nand driver
- OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
	- uses GPMC H/W engine for calculating ECC.
	- uses software library (lib/bch.h & nand_bch.h) for error correction.

- OMAP_ECC_BCH4_CODE_HW
	- uses GPMC H/W engine for calculating ECC.
	- uses ELM H/W engine for error correction.

With this patch omap2-nand driver supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+
Important:
- Selection of OMAP_ECC_BCHx_CODE_HW_DETECTION_SW requires,
	Kconfig: CONFIG_MTD_NAND_ECC_BCH: enables S/W based BCH ECC algorithm.

- Selection of OMAP_ECC_BCHx_CODE_HW requires,
	Kconfig: CONFIG_MTD_NAND_OMAP_BCH: enables ELM H/W module.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/Kconfig |  30 ++---------
 drivers/mtd/nand/omap2.c | 134 +++++++++++++++++++++--------------------------
 2 files changed, 63 insertions(+), 101 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..5836039 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
 
 config MTD_NAND_OMAP_BCH
 	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
-	tristate "Enable support for hardware BCH error correction"
+	tristate "Support hardware based BCH error correction"
 	default n
 	select BCH
-	select BCH_CONST_PARAMS
 	help
-	 Support for hardware BCH error correction.
-
-choice
-	prompt "BCH error correction capability"
-	depends on MTD_NAND_OMAP_BCH
-
-config MTD_NAND_OMAP_BCH8
-	bool "8 bits / 512 bytes (recommended)"
-	help
-	 Support correcting up to 8 bitflips per 512-byte block.
-	 This will use 13 bytes of spare area per 512 bytes of page data.
-	 This is the recommended mode, as 4-bit mode does not work
-	 on some OMAP3 revisions, due to a hardware bug.
-
-config MTD_NAND_OMAP_BCH4
-	bool "4 bits / 512 bytes"
-	help
-	 Support correcting up to 4 bitflips per 512-byte block.
-	 This will use 7 bytes of spare area per 512 bytes of page data.
-	 Note that this mode does not work on some OMAP3 revisions, due to a
-	 hardware bug. Please check your OMAP datasheet before selecting this
-	 mode.
-
-endchoice
+	  Some devices have built-in ELM hardware engine, which can be used to
+	  locate and correct errors when using BCH ECC scheme. This enables the
+	  driver support for same.
 
 if MTD_NAND_OMAP_BCH
 config BCH_CONST_M
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index fb96251..a783dae 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -27,6 +27,7 @@
 
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 #include <linux/bch.h>
+#include <linux/mtd/nand_bch.h>
 #endif
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/platform_data/elm.h>
@@ -144,7 +145,6 @@
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
 #define BADBLOCK_MARKER_LENGTH		2
-#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
@@ -188,7 +188,6 @@ struct omap_nand_info {
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
-	struct bch_control              *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1522,43 +1521,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_correct_data_bch - Decode received data and correct errors
- * @mtd: MTD device structure
- * @data: page data
- * @read_ecc: ecc read from nand flash
- * @calc_ecc: ecc read from HW ECC registers
- */
-static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
-				  u_char *read_ecc, u_char *calc_ecc)
-{
-	int i, count;
-	/* cannot correct more than 8 errors */
-	unsigned int errloc[8];
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-
-	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
-			   errloc);
-	if (count > 0) {
-		/* correct errors */
-		for (i = 0; i < count; i++) {
-			/* correct data only, not ecc bytes */
-			if (errloc[i] < 8*512)
-				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
-			pr_debug("corrected bitflip %u\n", errloc[i]);
-		}
-	} else if (count < 0) {
-		pr_err("ecc unrecoverable error\n");
-	}
-	return count;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1675,28 +1638,6 @@ static int is_elm_present(struct omap_nand_info *info,
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
- */
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-#else
-
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
@@ -1731,10 +1672,10 @@ static int omap_nand_probe(struct platform_device *pdev)
 	mtd->owner		= THIS_MODULE;
 	mtd->priv		= &info->nand;
 	nand_chip		= &info->nand;
+	nand_chip->ecc.priv	= NULL;
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-	info->bch		= NULL;
 
 	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 	info->of_node		= pdata->of_node;
@@ -1927,7 +1868,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		info->nand.ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1937,10 +1878,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		info->nand.ecc.priv		= nand_bch_init(mtd,
+							info->nand.ecc.size,
+							info->nand.ecc.bytes,
+							&info->nand.ecc.layout);
+		if (!info->nand.ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 		}
@@ -1951,6 +1893,39 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 #endif
 
+	case OMAP_ECC_BCH4_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
+		info->nand.ecc.mode		= NAND_ECC_HW;
+		info->nand.ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		info->nand.ecc.bytes		= 7 + 1;
+		info->nand.ecc.strength		= 4;
+		info->nand.ecc.hwctl		= omap3_enable_hwecc_bch;
+		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;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			err = -ENODEV;
+			goto out_release_mem_region;
+		}
+		/* define ECC layout */
+		ecclayout->eccbytes		= info->nand.ecc.bytes *
+							(mtd->writesize /
+							info->nand.ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
@@ -1959,7 +1934,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		info->nand.ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1969,10 +1944,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		info->nand.ecc.priv		= nand_bch_init(mtd,
+							info->nand.ecc.size,
+							info->nand.ecc.bytes,
+							&info->nand.ecc.layout);
+		if (!info->nand.ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2023,7 +1999,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* populate remaining info for custom ecc layout */
-	pr_info("%s: using custom ecc layout\n", DRIVER_NAME);
 	ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH
 						- ecclayout->eccbytes;
 	if (!(nand_chip->options & NAND_BUSWIDTH_16))
@@ -2061,7 +2036,12 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
-	omap3_free_bch(&info->mtd);
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+	if (info->nand.ecc.priv) {
+		nand_bch_free(info->nand.ecc.priv);
+		info->nand.ecc.priv = NULL;
+	}
+#endif
 	kfree(info);
 
 	return err;
@@ -2072,8 +2052,12 @@ static int omap_nand_remove(struct platform_device *pdev)
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(&info->mtd);
-
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+	if (info->nand.ecc.priv) {
+		nand_bch_free(info->nand.ecc.priv);
+		info->nand.ecc.priv = NULL;
+	}
+#endif
 	if (info->dma)
 		dma_release_channel(info->dma);
 
-- 
1.8.1



From pekon at ti.com  Fri Oct  4 15:49:48 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:48 +0530
Subject: [PATCH v7 6/6] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <1380916188-24206-1-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
Message-ID: <1380916188-24206-7-git-send-email-pekon@ti.com>

"Managed Device Resource" or devm_xx calls takes care of automatic freeing
of the resource in case of:
- failure during driver probe
- failure during resource allocation
- detaching or unloading of driver module (rmmod)
Reference: Documentation/driver-model/devres.txt

Though OMAP NAND driver handles freeing of resource allocation in most of
the cases, but using devm_xx provides more clean and effortless approach
to handle all such cases.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a783dae..0f2b0d1 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1658,7 +1658,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
+				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -1690,13 +1691,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->phys_base = res->start;
 	info->mem_size = resource_size(res);
 
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
+	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
+				info->mem_size,	pdev->dev.driver->name)) {
 		err = -EBUSY;
 		goto out_free_info;
 	}
 
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	info->nand.IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
+						info->mem_size);
 	if (!info->nand.IO_ADDR_R) {
 		err = -ENOMEM;
 		goto out_release_mem_region;
@@ -1799,8 +1801,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 			err = -ENODEV;
 			goto out_release_mem_region;
 		}
-		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-fifo", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-fifo", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_fifo, err);
@@ -1814,8 +1817,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 			err = -ENODEV;
 			goto out_release_mem_region;
 		}
-		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-count", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-count", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_count, err);
@@ -2031,10 +2035,10 @@ out_release_mem_region:
 	if (info->dma)
 		dma_release_channel(info->dma);
 	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);
 	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);
+	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
 out_free_info:
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 	if (info->nand.ecc.priv) {
@@ -2042,7 +2046,7 @@ out_free_info:
 		info->nand.ecc.priv = NULL;
 	}
 #endif
-	kfree(info);
+	devm_kfree(&pdev->dev, info);
 
 	return err;
 }
@@ -2062,15 +2066,15 @@ static int omap_nand_remove(struct platform_device *pdev)
 		dma_release_channel(info->dma);
 
 	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);
 	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);
 
 	/* Release NAND device, its internal structures and partitions */
 	nand_release(&info->mtd);
-	iounmap(info->nand.IO_ADDR_R);
-	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
+	devm_iounmap(&pdev->dev, info->nand.IO_ADDR_R);
+	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
+	devm_kfree(&pdev->dev, info);
 	return 0;
 }
 
-- 
1.8.1



From pekon at ti.com  Fri Oct  4 15:49:47 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 5 Oct 2013 01:19:47 +0530
Subject: [PATCH v7 5/6] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1380916188-24206-1-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
Message-ID: <1380916188-24206-6-git-send-email-pekon@ti.com>

DT property values for OMAP based gpmc-nand have been updated
to match changes in commit:
	6faf096 ARM: OMAP2+: cleaned-up DT support of various ECC schemes
Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 arch/arm/boot/dts/am335x-evm.dts   | 3 +--
 arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e8ec875..1aee6ac 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -269,7 +269,6 @@
 				reg = <0 0 0>; /* CS0, offset 0 */
 				nand-bus-width = <8>;
 				ti,nand-ecc-opt = "bch8";
-				gpmc,device-nand = "true";
 				gpmc,device-width = <1>;
 				gpmc,sync-clk-ps = <0>;
 				gpmc,cs-on-ns = <0>;
@@ -296,7 +295,7 @@
 
 				#address-cells = <1>;
 				#size-cells = <1>;
-				elm_id = <&elm>;
+				ti,elm-id = <&elm>;
 
 				/* MTD partition table */
 				partition at 0 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index e2249bc..501f863 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -105,7 +105,7 @@
 		reg = <1 0 0x08000000>;
 		nand-bus-width = <8>;
 
-		ti,nand-ecc-opt = "sw";
+		ti,nand-ecc-opt = "ham1";
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <36>;
 		gpmc,cs-wr-off-ns = <36>;
-- 
1.8.1



From joern at logfs.org  Fri Oct  4 18:02:58 2013
From: joern at logfs.org (=?utf-8?B?SsO2cm4=?= Engel)
Date: Fri, 4 Oct 2013 18:02:58 -0400
Subject: [PATCH] mtd: phram: Make phram 64-bit compatible
In-Reply-To: <524C4CF5.7060601@nsn.com>
References: <524C4CF5.7060601@nsn.com>
Message-ID: <20131004220258.GA26731@logfs.org>

On Wed, 2 October 2013 18:42:29 +0200, Alexander Sverdlin wrote:
> 
> mtd: phram: Make phram 64-bit compatible
> 
> phram was 32-bit limited by design. Machines are growing up, but phram
> module is still useful. Update it. The patch is bigger than minimum,
> because simple_strtoul() is obsolete.
> 
> Tested on MIPS64 and compile-tested for PPC (32 bit).
> 
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin at nsn.com>
Reviewed-by: Joern Engel <joern at logfs.org>

I quite like it.

J?rn

--
Antivirus is homeopathy for computers: This software was in contact with
malware in the past, so it?ll recognize other malware in the future.
$79
-- thegrugq


From computersforpeace at gmail.com  Fri Oct  4 20:06:49 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 4 Oct 2013 17:06:49 -0700
Subject: [PATCH 00/21] Armada 370/XP NAND support
In-Reply-To: <20131004194203.GB20476@localhost>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20130926195615.GK23337@ld-irv-0074.broadcom.com>
 <20130930122428.GA2417@localhost>
 <20131003000253.GX23337@ld-irv-0074.broadcom.com>
 <20131004194203.GB20476@localhost>
Message-ID: <20131005000649.GZ23337@ld-irv-0074.broadcom.com>

On Fri, Oct 04, 2013 at 04:42:04PM -0300, Ezequiel Garcia wrote:
> On Wed, Oct 02, 2013 at 05:02:53PM -0700, Brian Norris wrote:
> > On Mon, Sep 30, 2013 at 09:24:29AM -0300, Ezequiel Garcia wrote:
> > > Notice that this means you can control the ECC strength: since the ECC
> > > is always 30B, and it's calculated on the transfered chunk you can
> > > configure the controller to transfer the page in 1024B chunks and get a
> > > 30B ECC for each of this chunk, thus doubling the ECC strength.
> > 
> > This is a little odd. Your ECC HW is not parameterized by ECC strength,
> > but instead by ECC sector size? I think I have some comments for patch
> > 5, relevant to this topic.
> > 
> 
> Indeed. When ECC engine in the controller is set to do BCH, it always
> store a 30-byte ECC code. This 30-byte code is calculated on the
> transfered chunk, and since the chunk size is configurable we can
> effectively configure the ECC strength.
> 
> The specification says

Is there a public URL for the specification?

> the ECC BCH engine can correct up to 16-bits, which means:

Is this your interpretation, or are you quoting the spec?

> if the chunk is 2048 bytes you get BCH-4, and if the chunk
> is set to be 1024 bytes, you get BCH-8.

That doesn't really make sense to me. If you can't post a public URL,
can you paste the relevant text for this?

Most NAND specifies a required correctability of something like "correct
1 bit error per 512 bytes" or "correct 4 bits per 512 bytes". These are
not the same as "correct 1 bit per 2048 bytes" and "correct 4 bits per
2048 bytes", respectively, for obvious reasons.

So your "BCH-4" over a "2048 byte chunk" could be interpreted in
multiple ways. I'll list a few.

(1) BCH-4 usually means 4 bit correction over a 512 byte region, to
    match most SLC that might specify 4-bit correction. Applied to your
    hardware, it could possibly be that the 2048 byte region is actually
    4 smaller regions which are corrected separately, each with 4 bit
    correction. The ECC metadata just happens to be stored in 30 bytes
    of OOB (each 512-byte "sub-step" uses 7.5 bytes of spare area??)

    Another way to look at this: perhaps your ECC "chunk size" (the
    contiguous region over which your ECC is applied and transferred
    atomically) is different than the "correction region" (the region
    over which a certain number of bits may be corrected).

(2) Your BCH-4 over 2048 bytes really means what it says; it can only
    correct 4-bit in the 2048-byte area. This is sufficient for NAND
    that specify 1-bit correction per 512-bytes but not for those that
    specify 4-bit correction over 512-bytes.

Because an interpretation like (2) doesn't really match the NAND parts
you seem to be targeting, I'm inclined to think (1) is what the hardware
is doing. I also suspect (2) is wrong because the BCH algorithm (under
typical parameters) requires on the order of 6 to 8 bytes for storage,
regardless of the region it is correcting over. So "BCH-4" over 2048
bytes would only require 6 to 8 bytes of storage, not 30.

Barring more lucid documentation, you might want to verify this with
some tests. If you can support raw (no ECC) programming, this is a case
where you could induce bit errors and see how many can be corrected in
various patterns. But that's only necessary if your documentation sucks
too badly or is not public.

Regarding patch 5 (might as well mention it here), you are only checking
the ecc_strength_ds field for 4. You are not checking ecc_step_ds, which
likely will be 512 or 1024. Both parameters are relevant to determining
what ECC types are strong enough. But it's confusing enough right now to
even determine what your hardware means when you say "BCH-4", so we
might not be ready to handle this yet...

Brian


From computersforpeace at gmail.com  Fri Oct  4 20:27:13 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 4 Oct 2013 17:27:13 -0700
Subject: [PATCH 05/21] mtd: nand: pxa3xx: Add driver-specific ECC BCH
 support
In-Reply-To: <20131004194923.GC20476@localhost>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-6-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131003002440.GY23337@ld-irv-0074.broadcom.com>
 <20131004194923.GC20476@localhost>
Message-ID: <20131005002713.GA23337@ld-irv-0074.broadcom.com>

On Fri, Oct 04, 2013 at 04:49:24PM -0300, Ezequiel Garcia wrote:
> On Wed, Oct 02, 2013 at 05:24:40PM -0700, Brian Norris wrote:
> > On Thu, Sep 19, 2013 at 01:01:29PM -0300, Ezequiel Garcia wrote:
> > > This commit adds the BCH ECC support available in NFCv2 controller.
> > > Depending on the detected required strength the respective ECC layout
> > > is selected.
> > > 
> > > This commit adds an empty ECC layout, since support to access large
> > > pages is first required. Once that support is added, a proper ECC
> > > layout will be added as well.
> > > 
> > > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > > ---
> > >  drivers/mtd/nand/pxa3xx_nand.c | 53 ++++++++++++++++++++++++++++++++++++------
> > >  1 file changed, 46 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> > > index a0dabe6..86c343e 100644
> > > --- a/drivers/mtd/nand/pxa3xx_nand.c
> > > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> > 
> > ...
> > 
> > > @@ -1117,10 +1133,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
> > >  	pxa3xx_flash_ids[1].name = NULL;
> > >  	def = pxa3xx_flash_ids;
> > >  KEEP_CONFIG:
> > > -	chip->ecc.mode = NAND_ECC_HW;
> > > -	chip->ecc.size = host->page_size;
> > > -	chip->ecc.strength = 1;
> > > -
> > >  	if (info->reg_ndcr & NDCR_DWIDTH_M)
> > >  		chip->options |= NAND_BUSWIDTH_16;
> > >  
> > > @@ -1130,8 +1142,35 @@ KEEP_CONFIG:
> > >  		chip->bbt_options |= NAND_BBT_USE_FLASH;
> > >  	}
> > >  
> > > +	/* Device detection must be done with ECC disabled */
> > > +	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
> > > +		nand_writel(info, NDECCCTRL, 0x0);
> > > +
> > >  	if (nand_scan_ident(mtd, 1, def))
> > >  		return -ENODEV;
> > > +
> > > +	/* 1-step ECC over the entire detected page size */
> > > +	chip->ecc.mode = NAND_ECC_HW;
> > > +	chip->ecc.size = mtd->writesize;
> > 
> > Does the ECC really only work in one step? IOW, do you only correct
> > 1-bit for the entire page? That is under-spec'd for most NAND (they need
> > 1-bit/512-byte, or 4-bit/512-byte). This ecc.size should actually
> > reflect the correction region (typically 512B or 1024B), and even if
> > your buffer layout makes a step every 2KB (or 4KB or whatever), the ECC
> > step size *should* be smaller than that.
> > 
> > Or maybe I'm wrong, and you're actually using a weak 4-bit correction
> > over 2048 bytes.
> > 
> 
> I must admit I'm a bit confused by this ECC step concept. Having
> described the ECC engine in the cover-letter, what do you think
> the right choice should be?

I'm still not sure. But I'll defer that discussion to the cover-letter.

> IMO, given the ECC engine works on the entire FIFO (actually it works
> on the transfered chunk) it's a 1-step ECC.

That doesn't necessarily mean it's 1-step ECC. The step refers more to
the correction region than to the mechanics of transfer sizes.

> On the other side, a multiple step ECC, i.e. chip->ecc.size != mtd->writesize
> makes the NAND base calls the subpage() function and the driver crashes
> horribly when using UBIFS.

Which function? Read or write? AFAICT, neither relies on chip->ecc.size.

> I'm not sure why subpage should be called in that case, given we don't
> support that.

If you don't support writes, you can flag:
    chip->options |= NAND_NO_SUBPAGE_WRITE

And subpage reads are currently only enabled on soft-ECC with page size
larger than 512.

> > > +
> > > +	/*
> > > +	 * Armada370 variant supports BCH, which provides 4-bit strength
> > > +	 * and needs to be supported in a special way.
> > > +	 */
> > > +	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
> > 
> > Might there be other variants eventually that support BCH? Perhaps you
> > want to separate the property of "can use BCH" from "will use BCH"?
> > 
> 
> Yeah, probably. And maybe setting the BCH from the DT? The problem here
> is that because of the ECC choice being intimately related to the OOB
> location, this means the ECC choice is intimately related to the bad
> block markers.

Speaking of that: how do you deal with bad block markers, if your data
is actually placed in what is traditionally the "spare area"?

> IOW, the user can't really choose among ECC.

This means the choice of ECC must remain consistent across all users of
the NAND, but it doesn't mean there is no initial choice. A user could
choose to enable a higher ECC strength than what is technically required
by the flash.

> I guess this means the ECC choice is some sort of a hardware description
> and rightfully belongs to the DT. Right?

Yes, I think some description of ECC can be placed in DT. We're working
through a DT binding for Pekon's OMAP driver right now.

Brian


From motobud at gmail.com  Fri Oct  4 21:53:23 2013
From: motobud at gmail.com (Brent Taylor)
Date: Fri, 4 Oct 2013 20:53:23 -0500
Subject: [PATCH v2] ubifs; Add lz4hc compression
Message-ID: <CAP+RiCBN_VojAqYBfSV6eH=5FVej43j_hG7ouKLbRSi0m5gmTA@mail.gmail.com>

Artem,
   I replaced the Kconfig description with your suggestion slightly edited.

Konstarev,
   I haven't looked at what it would take to add lz4hc to mkfs.ubifs.
I wasn't planning on it, but I can take a look.

-- Brent

diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/compress.c
linux-3.12-rc3/fs/ubifs/compress.c
--- linux-3.12-rc3.orig/fs/ubifs/compress.c     2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/compress.c  2013-07-17 21:57:27.440653860 -0500
@@ -53,6 +53,22 @@
 };
 #endif

+#ifdef CONFIG_UBIFS_FS_LZ4HC
+static DEFINE_MUTEX(lz4hc_mutex);
+
+static struct ubifs_compressor lz4hc_compr = {
+       .compr_type = UBIFS_COMPR_LZ4HC,
+       .comp_mutex = &lz4hc_mutex,
+       .name = "lz4hc",
+       .capi_name = "lz4hc",
+};
+#else
+static struct ubifs_compressor lz4hc_compr = {
+       .compr_type = UBIFS_COMPR_LZ4HC,
+       .name = "lz4hc",
+};
+#endif
+
 #ifdef CONFIG_UBIFS_FS_ZLIB
 static DEFINE_MUTEX(deflate_mutex);
 static DEFINE_MUTEX(inflate_mutex);
@@ -224,10 +240,14 @@
 {
        int err;

-       err = compr_init(&lzo_compr);
+       err = compr_init(&lz4hc_compr);
        if (err)
                return err;

+       err = compr_init(&lzo_compr);
+       if (err)
+               goto out_lz4hc;
+
        err = compr_init(&zlib_compr);
        if (err)
                goto out_lzo;
@@ -237,6 +257,8 @@

 out_lzo:
        compr_exit(&lzo_compr);
+out_lz4hc:
+       compr_exit(&lz4hc_compr);
        return err;
 }

@@ -245,6 +267,7 @@
  */
 void ubifs_compressors_exit(void)
 {
+       compr_exit(&lz4hc_compr);
        compr_exit(&lzo_compr);
        compr_exit(&zlib_compr);
 }
diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/Kconfig
linux-3.12-rc3/fs/ubifs/Kconfig
--- linux-3.12-rc3.orig/fs/ubifs/Kconfig        2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/Kconfig     2013-10-04 20:25:16.767776913 -0500
@@ -29,6 +29,16 @@
           LZO compressor is generally faster than zlib but compresses worse.
           Say 'Y' if unsure.

+config UBIFS_FS_LZ4HC
+       bool "LZ4HC compression support" if UBIFS_FS_ADVANCED_COMPR
+       depends on UBIFS_FS && CRYPTO_LZ4HC
+       default y
+       help
+          LZ4HC generally beats LZO on decompression speed while provides a lot
+      better compression ratio (comparable to zlib). Compression speed is
+      generally slower compared to LZO, but faster compared to zlib.
+          Say 'Y' if unsure.
+
 config UBIFS_FS_ZLIB
        bool "ZLIB compression support" if UBIFS_FS_ADVANCED_COMPR
        depends on UBIFS_FS
diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/super.c
linux-3.12-rc3/fs/ubifs/super.c
--- linux-3.12-rc3.orig/fs/ubifs/super.c        2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/super.c     2013-09-30 23:01:06.899526709 -0500
@@ -1040,6 +1040,8 @@
                                return -ENOMEM;
                        if (!strcmp(name, "none"))
                                c->mount_opts.compr_type = UBIFS_COMPR_NONE;
+                       else if (!strcmp(name, "lz4hc"))
+                               c->mount_opts.compr_type = UBIFS_COMPR_LZ4HC;
                        else if (!strcmp(name, "lzo"))
                                c->mount_opts.compr_type = UBIFS_COMPR_LZO;
                        else if (!strcmp(name, "zlib"))
diff -uN -uNr linux-3.12-rc3.orig/fs/ubifs/ubifs-media.h
linux-3.12-rc3/fs/ubifs/ubifs-media.h
--- linux-3.12-rc3.orig/fs/ubifs/ubifs-media.h  2013-09-29
17:02:38.000000000 -0500
+++ linux-3.12-rc3/fs/ubifs/ubifs-media.h       2013-10-04
20:25:58.839777442 -0500
@@ -332,12 +332,14 @@
  * UBIFS_COMPR_NONE: no compression
  * UBIFS_COMPR_LZO: LZO compression
  * UBIFS_COMPR_ZLIB: ZLIB compression
+ * UBIFS_COMPR_LZ4HC: LZ4HC compression
  * UBIFS_COMPR_TYPES_CNT: count of supported compression types
  */
 enum {
        UBIFS_COMPR_NONE,
        UBIFS_COMPR_LZO,
        UBIFS_COMPR_ZLIB,
+       UBIFS_COMPR_LZ4HC,
        UBIFS_COMPR_TYPES_CNT,
 };


From eliedebrauwer at gmail.com  Sat Oct  5 02:53:21 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Sat,  5 Oct 2013 08:53:21 +0200
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in mkfs.ubifs
Message-ID: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>

Brent et all,

I was bored last night and while following the thread on the lz4hc 
compression for ubifs got my attention so I decided to give a go at
implementing in. Below you can find a patch which does just that.

An lz4hc and favor_lz4hc compr type, they mimick lzo and favor_lzo 
but use lz4hc instead of lzo.

In order to use lz4hc I included 3 files from the lz4 project since
lz4 is not yet available in a conventient modular form (suggestions
to fix this are welcome).

In the meantime I saw however that Brent was also considering adding
lz4hc support mkfs.ubifs so I'm making a v0 zero post either to serve
as input for review comment (mainly on handling the lz4 dependency)
and then I'll take care of cleaning up and testing it myself, or just
to serve as some reference to the implementation of Brent, let me know
of you want some polishing up on this version or are already in an
advanced phase of a solution of yourself. 

(Yes, it's called v0, it's still untested but I would like input on 
the lz4 dependency handling and the extension of the options, or 
do we see something feasible where we contain lzo/lz4hc and zlib on 
the fly, suggestions welcome). 

my 2 cents
E. 
 

Signed-off-by: Elie De Brauwer <eliedebrauwer at gmail.com>
---
 Makefile                 |    2 +-
 mkfs.ubifs/README        |    1 +
 mkfs.ubifs/compr.c       |   64 ++--
 mkfs.ubifs/compr.h       |    1 +
 mkfs.ubifs/lz4/lz4.h     |  205 ++++++++++++
 mkfs.ubifs/lz4/lz4hc.c   |  817 ++++++++++++++++++++++++++++++++++++++++++++++
 mkfs.ubifs/lz4/lz4hc.h   |  111 +++++++
 mkfs.ubifs/mkfs.ubifs.c  |   33 +-
 mkfs.ubifs/ubifs-media.h |    2 +
 mkfs.ubifs/ubifs.h       |    2 +
 10 files changed, 1203 insertions(+), 35 deletions(-)
 create mode 100644 mkfs.ubifs/lz4/lz4.h
 create mode 100644 mkfs.ubifs/lz4/lz4hc.c
 create mode 100644 mkfs.ubifs/lz4/lz4hc.h

diff --git a/Makefile b/Makefile
index bf57a13..f79b08a 100644
--- a/Makefile
+++ b/Makefile
@@ -102,7 +102,7 @@ $(call _mkdep,lib/,libmtd.a)
 #
 # Utils in mkfs.ubifs subdir
 #
-obj-mkfs.ubifs = crc16.o lpt.o compr.o devtable.o \
+obj-mkfs.ubifs = crc16.o lpt.o compr.o lz4/lz4hc.o devtable.o \
 	hashtable/hashtable.o hashtable/hashtable_itr.o
 LDLIBS_mkfs.ubifs = -lz -llzo2 -lm -luuid
 $(call mkdep,mkfs.ubifs/,mkfs.ubifs,,ubi-utils/libubi.a)
diff --git a/mkfs.ubifs/README b/mkfs.ubifs/README
index 4fbaa7d..249aaa6 100644
--- a/mkfs.ubifs/README
+++ b/mkfs.ubifs/README
@@ -8,3 +8,4 @@ UBIFS File System - Make File System program
 * defs.h is a bunch of definitions to smooth things over.
 * lpt.c is a selection of functions copied from fs/ubifs/lpt.c from the linux kernel, and amended.
 * hashtable/* was downloaded from http://www.cl.cam.ac.uk/~cwc22/hashtable/
+* lz4/* is based upon https://code.google.com/p/lz4/ lz4-r106.tar.gz
\ No newline at end of file
diff --git a/mkfs.ubifs/compr.c b/mkfs.ubifs/compr.c
index 4152b6a..d9886b4 100644
--- a/mkfs.ubifs/compr.c
+++ b/mkfs.ubifs/compr.c
@@ -34,6 +34,7 @@
 #include "compr.h"
 #include "ubifs-media.h"
 #include "mkfs.ubifs.h"
+#include "lz4/lz4hc.h"
 
 static void *lzo_mem;
 static unsigned long long errcnt = 0;
@@ -104,6 +105,20 @@ static int lzo_compress(void *in_buf, size_t in_len, void *out_buf,
 	return 0;
 }
 
+static int lz4hc_compress(void *in_buf, size_t in_len, void *out_buf,
+			size_t *out_len)
+{
+	int ret;
+	ret = LZ4_compressHC_limitedOutput(in_buf, out_buf, in_len, *out_len);
+
+	if (ret != 0) {
+		errcnt += 1;
+		return -1;
+	}
+
+	return 0;
+}
+
 static int no_compress(void *in_buf, size_t in_len, void *out_buf,
 		       size_t *out_len)
 {
@@ -114,43 +129,49 @@ static int no_compress(void *in_buf, size_t in_len, void *out_buf,
 
 static char *zlib_buf;
 
-static int favor_lzo_compress(void *in_buf, size_t in_len, void *out_buf,
-			       size_t *out_len, int *type)
+static int favor_alt_compress(void *in_buf, size_t in_len, void *out_buf,
+			      size_t *out_len, int *type, int lzo)
 {
-	int lzo_ret, zlib_ret;
-	size_t lzo_len, zlib_len;
-
-	lzo_len = zlib_len = *out_len;
-	lzo_ret = lzo_compress(in_buf, in_len, out_buf, &lzo_len);
+	int alt_ret, zlib_ret;
+	size_t alt_len, zlib_len;
+
+	alt_len = zlib_len = *out_len;
+	if (lzo)
+		alt_ret = lzo_compress(in_buf, in_len, out_buf, &alt_len);
+	else
+		alt_ret = lz4hc_compress(in_buf, in_len, out_buf, &alt_len);
 	zlib_ret = zlib_deflate(in_buf, in_len, zlib_buf, &zlib_len);
 
-	if (lzo_ret && zlib_ret)
+	if (alt_ret && zlib_ret)
 		/* Both compressors failed */
 		return -1;
 
-	if (!lzo_ret && !zlib_ret) {
+	if (!alt_ret && !zlib_ret) {
 		double percent;
 
 		/* Both compressors succeeded */
-		if (lzo_len <= zlib_len )
-			goto select_lzo;
+		if (alt_len <= zlib_len )
+			goto select_alt;
 
-		percent = (double)zlib_len / (double)lzo_len;
+		percent = (double)zlib_len / (double)alt_len;
 		percent *= 100;
 		if (percent > 100 - c->favor_percent)
-			goto select_lzo;
+			goto select_alt;
 		goto select_zlib;
 	}
 
-	if (lzo_ret)
+	if (alt_ret)
 		/* Only zlib compressor succeeded */
 		goto select_zlib;
 
-	/* Only LZO compressor succeeded */
+	/* Only alternative compressor succeeded */
 
-select_lzo:
-	*out_len = lzo_len;
-	*type = MKFS_UBIFS_COMPR_LZO;
+select_alt:
+	*out_len = alt_len;
+	if (lzo)
+		*type = MKFS_UBIFS_COMPR_LZO;
+	else
+		*type = MKFS_UBIFS_COMPR_LZ4HC;
 	return 0;
 
 select_zlib:
@@ -170,10 +191,13 @@ int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
 		return MKFS_UBIFS_COMPR_NONE;
 	}
 
-	if (c->favor_lzo)
-		ret = favor_lzo_compress(in_buf, in_len, out_buf, out_len, &type);
+	if (c->favor_lzo || c->favor_lz4hc)
+		ret = favor_alt_compress(in_buf, in_len, out_buf, out_len, &type, c->favor_lzo);
 	else {
 		switch (type) {
+		case MKFS_UBIFS_COMPR_LZ4HC:
+			ret = lz4hc_compress(in_buf, in_len, out_buf, out_len);
+			break;
 		case MKFS_UBIFS_COMPR_LZO:
 			ret = lzo_compress(in_buf, in_len, out_buf, out_len);
 			break;
diff --git a/mkfs.ubifs/compr.h b/mkfs.ubifs/compr.h
index e3dd95c..a20033c 100644
--- a/mkfs.ubifs/compr.h
+++ b/mkfs.ubifs/compr.h
@@ -36,6 +36,7 @@ enum compression_type
 	MKFS_UBIFS_COMPR_NONE,
 	MKFS_UBIFS_COMPR_LZO,
 	MKFS_UBIFS_COMPR_ZLIB,
+	MKFS_UBIFS_COMPR_LZ4HC,
 };
 
 int compress_data(void *in_buf, size_t in_len, void *out_buf, size_t *out_len,
diff --git a/mkfs.ubifs/lz4/lz4.h b/mkfs.ubifs/lz4/lz4.h
new file mode 100644
index 0000000..f9aea72
--- /dev/null
+++ b/mkfs.ubifs/lz4/lz4.h
@@ -0,0 +1,205 @@
+/*
+   LZ4 - Fast LZ compression algorithm
+   Header File
+   Copyright (C) 2011-2013, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+#pragma once
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+//**************************************
+// Compiler Options
+//**************************************
+#if defined(_MSC_VER) && !defined(__cplusplus)   // Visual Studio
+#  define inline __inline           // Visual C is not C99, but supports some kind of inline
+#endif
+
+
+//****************************
+// Simple Functions
+//****************************
+
+int LZ4_compress        (const char* source, char* dest, int inputSize);
+int LZ4_decompress_safe (const char* source, char* dest, int inputSize, int maxOutputSize);
+
+/*
+LZ4_compress() :
+    Compresses 'inputSize' bytes from 'source' into 'dest'.
+    Destination buffer must be already allocated,
+    and must be sized to handle worst cases situations (input data not compressible)
+    Worst case size evaluation is provided by function LZ4_compressBound()
+    inputSize : Max supported value is ~1.9GB
+    return : the number of bytes written in buffer dest
+             or 0 if the compression fails
+
+LZ4_decompress_safe() :
+    maxOutputSize : is the size of the destination buffer (which must be already allocated)
+    return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize)
+             If the source stream is detected malformed, the function will stop decoding and return a negative result.
+             This function is protected against buffer overflow exploits (never writes outside of output buffer, and never reads outside of input buffer). Therefore, it is protected against malicious data packets
+*/
+
+
+//****************************
+// Advanced Functions
+//****************************
+
+static inline int LZ4_compressBound(int isize)   { return ((isize) + ((isize)/255) + 16); }
+#define           LZ4_COMPRESSBOUND(    isize)            ((isize) + ((isize)/255) + 16)
+
+/*
+LZ4_compressBound() :
+    Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible)
+    primarily useful for memory allocation of output buffer.
+    inline function is recommended for the general case,
+    macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation).
+
+    isize  : is the input size. Max supported value is ~1.9GB
+    return : maximum output size in a "worst case" scenario
+    note : this function is limited by "int" range (2^31-1)
+*/
+
+
+int LZ4_compress_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
+
+/*
+LZ4_compress_limitedOutput() :
+    Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
+    If it cannot achieve it, compression will stop, and result of the function will be zero.
+    This function never writes outside of provided output buffer.
+
+    inputSize  : Max supported value is ~1.9GB
+    maxOutputSize : is the size of the destination buffer (which must be already allocated)
+    return : the number of bytes written in buffer 'dest'
+             or 0 if the compression fails
+*/
+
+
+int LZ4_decompress_fast (const char* source, char* dest, int outputSize);
+
+/*
+LZ4_decompress_fast() :
+    outputSize : is the original (uncompressed) size
+    return : the number of bytes read from the source buffer (in other words, the compressed size)
+             If the source stream is malformed, the function will stop decoding and return a negative result.
+    note : This function is a bit faster than LZ4_decompress_safe()
+           This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet.
+           Use this function preferably into a trusted environment (data to decode comes from a trusted source).
+           Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes.
+*/
+
+int LZ4_decompress_safe_partial (const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize);
+
+/*
+LZ4_decompress_safe_partial() :
+    This function decompress a compressed block of size 'inputSize' at position 'source'
+    into output buffer 'dest' of size 'maxOutputSize'.
+    The function stops decompressing operation as soon as 'targetOutputSize' has been reached,
+    reducing decompression time.
+    return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize)
+       Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
+             Always control how many bytes were decoded.
+             If the source stream is detected malformed, the function will stop decoding and return a negative result.
+             This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
+*/
+
+
+//****************************
+// Stream Functions
+//****************************
+
+void* LZ4_create (const char* inputBuffer);
+int   LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize);
+int   LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize);
+char* LZ4_slideInputBuffer (void* LZ4_Data);
+int   LZ4_free (void* LZ4_Data);
+
+/* 
+These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks.
+In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function :
+
+void* LZ4_create (const char* inputBuffer);
+The result of the function is the (void*) pointer on the LZ4 Data Structure.
+This pointer will be needed in all other functions.
+If the pointer returned is NULL, then the allocation has failed, and compression must be aborted.
+The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer.
+The input buffer must be already allocated, and size at least 192KB.
+'inputBuffer' will also be the 'const char* source' of the first block.
+
+All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'.
+To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue().
+Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(), 
+but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one.
+If next block does not begin immediately after the previous one, the compression will fail (return 0).
+
+When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : 
+char* LZ4_slideInputBuffer(void* LZ4_Data);
+must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer.
+Note that, for this function to work properly, minimum size of an input buffer must be 192KB.
+==> The memory position where the next input data block must start is provided as the result of the function.
+
+Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual.
+
+When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure.
+*/
+
+
+int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int inputSize, int maxOutputSize);
+int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int outputSize);
+
+/*
+*_withPrefix64k() :
+    These decoding functions work the same as their "normal name" versions,
+    but can use up to 64KB of data in front of 'char* dest'.
+    These functions are necessary to decode inter-dependant blocks.
+*/
+
+
+//****************************
+// Obsolete Functions
+//****************************
+
+static inline int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
+static inline int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
+
+/*
+These functions are deprecated and should no longer be used.
+They are provided here for compatibility with existing user programs.
+*/
+
+
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/mkfs.ubifs/lz4/lz4hc.c b/mkfs.ubifs/lz4/lz4hc.c
new file mode 100644
index 0000000..d2b402d
--- /dev/null
+++ b/mkfs.ubifs/lz4/lz4hc.c
@@ -0,0 +1,817 @@
+/*
+   LZ4 HC - High Compression Mode of LZ4
+   Copyright (C) 2011-2013, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+
+//**************************************
+// Memory routines
+//**************************************
+#include <stdlib.h>   // calloc, free
+#define ALLOCATOR(s)  calloc(1,s)
+#define FREEMEM       free
+#include <string.h>   // memset, memcpy
+#define MEM_INIT      memset
+
+
+//**************************************
+// CPU Feature Detection
+//**************************************
+// 32 or 64 bits ?
+#if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \
+  || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \
+  || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \
+  || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) )   // Detects 64 bits mode
+#  define LZ4_ARCH64 1
+#else
+#  define LZ4_ARCH64 0
+#endif
+
+// Little Endian or Big Endian ?
+// Overwrite the #define below if you know your architecture endianess
+#if defined (__GLIBC__)
+#  include <endian.h>
+#  if (__BYTE_ORDER == __BIG_ENDIAN)
+#     define LZ4_BIG_ENDIAN 1
+#  endif
+#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN))
+#  define LZ4_BIG_ENDIAN 1
+#elif defined(__sparc) || defined(__sparc__) \
+   || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \
+   || defined(__hpux)  || defined(__hppa) \
+   || defined(_MIPSEB) || defined(__s390__)
+#  define LZ4_BIG_ENDIAN 1
+#else
+// Little Endian assumed. PDP Endian and other very rare endian format are unsupported.
+#endif
+
+// Unaligned memory access is automatically enabled for "common" CPU, such as x86.
+// For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
+// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance
+#if defined(__ARM_FEATURE_UNALIGNED)
+#  define LZ4_FORCE_UNALIGNED_ACCESS 1
+#endif
+
+// Define this parameter if your target system or compiler does not support hardware bit count
+#if defined(_MSC_VER) && defined(_WIN32_WCE)            // Visual Studio for Windows CE does not support Hardware bit count
+#  define LZ4_FORCE_SW_BITCOUNT
+#endif
+
+
+//**************************************
+// Compiler Options
+//**************************************
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   // C99
+  /* "restrict" is a known keyword */
+#else
+#  define restrict  // Disable restrict
+#endif
+
+#ifdef _MSC_VER    // Visual Studio
+#  define FORCE_INLINE static __forceinline
+#  include <intrin.h>                    // For Visual 2005
+#  if LZ4_ARCH64   // 64-bits
+#    pragma intrinsic(_BitScanForward64) // For Visual 2005
+#    pragma intrinsic(_BitScanReverse64) // For Visual 2005
+#  else            // 32-bits
+#    pragma intrinsic(_BitScanForward)   // For Visual 2005
+#    pragma intrinsic(_BitScanReverse)   // For Visual 2005
+#  endif
+#  pragma warning(disable : 4127)        // disable: C4127: conditional expression is constant
+#  pragma warning(disable : 4701)        // disable: C4701: potentially uninitialized local variable used
+#else 
+#  ifdef __GNUC__
+#    define FORCE_INLINE static inline __attribute__((always_inline))
+#  else
+#    define FORCE_INLINE static inline
+#  endif
+#endif
+
+#ifdef _MSC_VER  // Visual Studio
+#  define lz4_bswap16(x) _byteswap_ushort(x)
+#else
+#  define lz4_bswap16(x)  ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
+#endif
+
+
+//**************************************
+// Includes
+//**************************************
+#include "lz4hc.h"
+#include "lz4.h"
+
+
+//**************************************
+// Basic Types
+//**************************************
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   // C99
+# include <stdint.h>
+  typedef uint8_t  BYTE;
+  typedef uint16_t U16;
+  typedef uint32_t U32;
+  typedef  int32_t S32;
+  typedef uint64_t U64;
+#else
+  typedef unsigned char       BYTE;
+  typedef unsigned short      U16;
+  typedef unsigned int        U32;
+  typedef   signed int        S32;
+  typedef unsigned long long  U64;
+#endif
+
+#if defined(__GNUC__)  && !defined(LZ4_FORCE_UNALIGNED_ACCESS)
+#  define _PACKED __attribute__ ((packed))
+#else
+#  define _PACKED
+#endif
+
+#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
+#  ifdef __IBMC__
+#    pragma pack(1)
+#  else
+#    pragma pack(push, 1)
+#  endif
+#endif
+
+typedef struct _U16_S { U16 v; } _PACKED U16_S;
+typedef struct _U32_S { U32 v; } _PACKED U32_S;
+typedef struct _U64_S { U64 v; } _PACKED U64_S;
+
+#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
+#  pragma pack(pop)
+#endif
+
+#define A64(x) (((U64_S *)(x))->v)
+#define A32(x) (((U32_S *)(x))->v)
+#define A16(x) (((U16_S *)(x))->v)
+
+
+//**************************************
+// Constants
+//**************************************
+#define MINMATCH 4
+
+#define DICTIONARY_LOGSIZE 16
+#define MAXD (1<<DICTIONARY_LOGSIZE)
+#define MAXD_MASK ((U32)(MAXD - 1))
+#define MAX_DISTANCE (MAXD - 1)
+
+#define HASH_LOG (DICTIONARY_LOGSIZE-1)
+#define HASHTABLESIZE (1 << HASH_LOG)
+#define HASH_MASK (HASHTABLESIZE - 1)
+
+#define MAX_NB_ATTEMPTS 256
+
+#define ML_BITS  4
+#define ML_MASK  (size_t)((1U<<ML_BITS)-1)
+#define RUN_BITS (8-ML_BITS)
+#define RUN_MASK ((1U<<RUN_BITS)-1)
+
+#define COPYLENGTH 8
+#define LASTLITERALS 5
+#define MFLIMIT (COPYLENGTH+MINMATCH)
+#define MINLENGTH (MFLIMIT+1)
+#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
+
+#define KB *(1U<<10)
+#define MB *(1U<<20)
+#define GB *(1U<<30)
+
+
+//**************************************
+// Architecture-specific macros
+//**************************************
+#if LZ4_ARCH64   // 64-bit
+#  define STEPSIZE 8
+#  define LZ4_COPYSTEP(s,d)     A64(d) = A64(s); d+=8; s+=8;
+#  define LZ4_COPYPACKET(s,d)   LZ4_COPYSTEP(s,d)
+#  define UARCH U64
+#  define AARCH A64
+#  define HTYPE                 U32
+#  define INITBASE(b,s)         const BYTE* const b = s
+#else   // 32-bit
+#  define STEPSIZE 4
+#  define LZ4_COPYSTEP(s,d)     A32(d) = A32(s); d+=4; s+=4;
+#  define LZ4_COPYPACKET(s,d)   LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
+#  define UARCH U32
+#  define AARCH A32
+//#  define HTYPE                 const BYTE*
+//#  define INITBASE(b,s)         const int b = 0
+#  define HTYPE                 U32
+#  define INITBASE(b,s)         const BYTE* const b = s
+#endif
+
+#if defined(LZ4_BIG_ENDIAN)
+#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
+#  define LZ4_WRITE_LITTLEENDIAN_16(p,i)  { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
+#else   // Little Endian
+#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
+#  define LZ4_WRITE_LITTLEENDIAN_16(p,v)  { A16(p) = v; p+=2; }
+#endif
+
+
+//************************************************************
+// Local Types
+//************************************************************
+typedef struct 
+{
+    const BYTE* inputBuffer;
+    const BYTE* base;
+    const BYTE* end;
+    HTYPE hashTable[HASHTABLESIZE];
+    U16 chainTable[MAXD];
+    const BYTE* nextToUpdate;
+} LZ4HC_Data_Structure;
+
+
+//**************************************
+// Macros
+//**************************************
+#define LZ4_WILDCOPY(s,d,e)    do { LZ4_COPYPACKET(s,d) } while (d<e);
+#define LZ4_BLINDCOPY(s,d,l)   { BYTE* e=d+l; LZ4_WILDCOPY(s,d,e); d=e; }
+#define HASH_FUNCTION(i)       (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
+#define HASH_VALUE(p)          HASH_FUNCTION(A32(p))
+#define HASH_POINTER(p)        (HashTable[HASH_VALUE(p)] + base)
+#define DELTANEXT(p)           chainTable[(size_t)(p) & MAXD_MASK] 
+#define GETNEXT(p)             ((p) - (size_t)DELTANEXT(p))
+
+
+//**************************************
+// Private functions
+//**************************************
+#if LZ4_ARCH64
+
+FORCE_INLINE int LZ4_NbCommonBytes (register U64 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanReverse64( &r, val );
+    return (int)(r>>3);
+#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_clzll(val) >> 3); 
+#  else
+    int r;
+    if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
+    if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
+    r += (!val);
+    return r;
+#  endif
+#else
+#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r = 0;
+    _BitScanForward64( &r, val );
+    return (int)(r>>3);
+#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_ctzll(val) >> 3); 
+#  else
+    static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
+    return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
+#  endif
+#endif
+}
+
+#else
+
+FORCE_INLINE int LZ4_NbCommonBytes (register U32 val)
+{
+#if defined(LZ4_BIG_ENDIAN)
+#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r;
+    _BitScanReverse( &r, val );
+    return (int)(r>>3);
+#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_clz(val) >> 3); 
+#  else
+    int r;
+    if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
+    r += (!val);
+    return r;
+#  endif
+#else
+#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    unsigned long r;
+    _BitScanForward( &r, val );
+    return (int)(r>>3);
+#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
+    return (__builtin_ctz(val) >> 3); 
+#  else
+    static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
+    return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+#  endif
+#endif
+}
+
+#endif
+
+
+FORCE_INLINE void LZ4_initHC (LZ4HC_Data_Structure* hc4, const BYTE* base)
+{
+    MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
+    MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
+    hc4->nextToUpdate = base + 1;
+    hc4->base = base;
+    hc4->inputBuffer = base;
+    hc4->end = base;
+}
+
+
+void* LZ4_createHC (const char* inputBuffer)
+{
+    void* hc4 = ALLOCATOR(sizeof(LZ4HC_Data_Structure));
+    LZ4_initHC ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer);
+    return hc4;
+}
+
+
+int LZ4_freeHC (void* LZ4HC_Data)
+{
+    FREEMEM(LZ4HC_Data);
+    return (0);
+}
+
+
+// Update chains up to ip (excluded)
+FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
+{
+    U16*   chainTable = hc4->chainTable;
+    HTYPE* HashTable  = hc4->hashTable;
+    INITBASE(base,hc4->base);
+
+    while(hc4->nextToUpdate < ip)
+    {
+        const BYTE* const p = hc4->nextToUpdate;
+        size_t delta = (p) - HASH_POINTER(p); 
+        if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; 
+        DELTANEXT(p) = (U16)delta; 
+        HashTable[HASH_VALUE(p)] = (HTYPE)((p) - base);
+        hc4->nextToUpdate++;
+    }
+}
+
+
+char* LZ4_slideInputBufferHC(void* LZ4HC_Data)
+{
+    LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data;
+    U32 distance = (U32)(hc4->end - hc4->inputBuffer) - 64 KB;
+    distance = (distance >> 16) << 16;   // Must be a multiple of 64 KB
+    LZ4HC_Insert(hc4, hc4->end - MINMATCH);
+    memcpy((void*)(hc4->end - 64 KB - distance), (const void*)(hc4->end - 64 KB), 64 KB);
+    hc4->nextToUpdate -= distance;
+    hc4->base -= distance;
+    if ((U32)(hc4->inputBuffer - hc4->base) > 1 GB + 64 KB)   // Avoid overflow
+    {
+        int i;
+        hc4->base += 1 GB;
+        for (i=0; i<HASHTABLESIZE; i++) hc4->hashTable[i] -= 1 GB;
+    }
+    hc4->end -= distance;
+    return (char*)(hc4->end);
+}
+
+
+FORCE_INLINE size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit)
+{
+    const BYTE* p1t = p1;
+
+    while (p1t<matchlimit-(STEPSIZE-1))
+    {
+        UARCH diff = AARCH(p2) ^ AARCH(p1t);
+        if (!diff) { p1t+=STEPSIZE; p2+=STEPSIZE; continue; }
+        p1t += LZ4_NbCommonBytes(diff);
+        return (p1t - p1);
+    }
+    if (LZ4_ARCH64) if ((p1t<(matchlimit-3)) && (A32(p2) == A32(p1t))) { p1t+=4; p2+=4; }
+    if ((p1t<(matchlimit-1)) && (A16(p2) == A16(p1t))) { p1t+=2; p2+=2; }
+    if ((p1t<matchlimit) && (*p2 == *p1t)) p1t++;
+    return (p1t - p1);
+}
+
+
+FORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* const matchlimit, const BYTE** matchpos)
+{
+    U16* const chainTable = hc4->chainTable;
+    HTYPE* const HashTable = hc4->hashTable;
+    const BYTE* ref;
+    INITBASE(base,hc4->base);
+    int nbAttempts=MAX_NB_ATTEMPTS;
+    size_t repl=0, ml=0;
+    U16 delta=0;  // useless assignment, to remove an uninitialization warning
+
+    // HC4 match finder
+    LZ4HC_Insert(hc4, ip);
+    ref = HASH_POINTER(ip);
+
+#define REPEAT_OPTIMIZATION
+#ifdef REPEAT_OPTIMIZATION
+    // Detect repetitive sequences of length <= 4
+    if ((U32)(ip-ref) <= 4)        // potential repetition
+    {
+        if (A32(ref) == A32(ip))   // confirmed
+        {
+            delta = (U16)(ip-ref);
+            repl = ml  = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;
+            *matchpos = ref;
+        }
+        ref = GETNEXT(ref);
+    }
+#endif
+
+    while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts))
+    {
+        nbAttempts--;
+        if (*(ref+ml) == *(ip+ml))
+        if (A32(ref) == A32(ip))
+        {
+            size_t mlt = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH;
+            if (mlt > ml) { ml = mlt; *matchpos = ref; }
+        }
+        ref = GETNEXT(ref);
+    }
+
+#ifdef REPEAT_OPTIMIZATION
+    // Complete table
+    if (repl)
+    {
+        const BYTE* ptr = ip;
+        const BYTE* end;
+
+        end = ip + repl - (MINMATCH-1);
+        while(ptr < end-delta)
+        {
+            DELTANEXT(ptr) = delta;    // Pre-Load
+            ptr++;
+        }
+        do
+        {
+            DELTANEXT(ptr) = delta;    
+            HashTable[HASH_VALUE(ptr)] = (HTYPE)((ptr) - base);     // Head of chain
+            ptr++;
+        } while(ptr < end);
+        hc4->nextToUpdate = end;
+    }
+#endif 
+
+    return (int)ml;
+}
+
+
+FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos)
+{
+    U16* const  chainTable = hc4->chainTable;
+    HTYPE* const HashTable = hc4->hashTable;
+    INITBASE(base,hc4->base);
+    const BYTE*  ref;
+    int nbAttempts = MAX_NB_ATTEMPTS;
+    int delta = (int)(ip-startLimit);
+
+    // First Match
+    LZ4HC_Insert(hc4, ip);
+    ref = HASH_POINTER(ip);
+
+    while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts))
+    {
+        nbAttempts--;
+        if (*(startLimit + longest) == *(ref - delta + longest))
+        if (A32(ref) == A32(ip))
+        {
+#if 1
+            const BYTE* reft = ref+MINMATCH;
+            const BYTE* ipt = ip+MINMATCH;
+            const BYTE* startt = ip;
+
+            while (ipt<matchlimit-(STEPSIZE-1))
+            {
+                UARCH diff = AARCH(reft) ^ AARCH(ipt);
+                if (!diff) { ipt+=STEPSIZE; reft+=STEPSIZE; continue; }
+                ipt += LZ4_NbCommonBytes(diff);
+                goto _endCount;
+            }
+            if (LZ4_ARCH64) if ((ipt<(matchlimit-3)) && (A32(reft) == A32(ipt))) { ipt+=4; reft+=4; }
+            if ((ipt<(matchlimit-1)) && (A16(reft) == A16(ipt))) { ipt+=2; reft+=2; }
+            if ((ipt<matchlimit) && (*reft == *ipt)) ipt++;
+_endCount:
+            reft = ref;
+#else
+            // Easier for code maintenance, but unfortunately slower too
+            const BYTE* startt = ip;
+            const BYTE* reft = ref;
+            const BYTE* ipt = ip + MINMATCH + LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit);
+#endif
+
+            while ((startt>startLimit) && (reft > hc4->inputBuffer) && (startt[-1] == reft[-1])) {startt--; reft--;}
+
+            if ((ipt-startt) > longest)
+            {
+                longest = (int)(ipt-startt);
+                *matchpos = reft;
+                *startpos = startt;
+            }
+        }
+        ref = GETNEXT(ref);
+    }
+
+    return longest;
+}
+
+
+typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
+
+FORCE_INLINE int LZ4HC_encodeSequence (
+                       const BYTE** ip,
+                       BYTE** op,
+                       const BYTE** anchor,
+                       int matchLength,
+                       const BYTE* ref,
+                       limitedOutput_directive limitedOutputBuffer,
+                       BYTE* oend)
+{
+    int length;
+    BYTE* token;
+
+    // Encode Literal length
+    length = (int)(*ip - *anchor);
+    token = (*op)++;
+    if ((limitedOutputBuffer) && ((*op + length + (2 + 1 + LASTLITERALS) + (length>>8)) > oend)) return 1;   // Check output limit
+    if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255;  *(*op)++ = (BYTE)len; } 
+    else *token = (BYTE)(length<<ML_BITS);
+
+    // Copy Literals
+    LZ4_BLINDCOPY(*anchor, *op, length);
+
+    // Encode Offset
+    LZ4_WRITE_LITTLEENDIAN_16(*op,(U16)(*ip-ref));
+
+    // Encode MatchLength
+    length = (int)(matchLength-MINMATCH);
+    if ((limitedOutputBuffer) && (*op + (1 + LASTLITERALS) + (length>>8) > oend)) return 1;   // Check output limit
+    if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; } 
+    else *token += (BYTE)(length);	
+
+    // Prepare next loop
+    *ip += matchLength;
+    *anchor = *ip; 
+
+    return 0;
+}
+
+
+static int LZ4HC_compress_generic (
+                 void* ctxvoid,
+                 const char* source, 
+                 char* dest,
+                 int inputSize,
+                 int maxOutputSize,
+                 limitedOutput_directive limit
+                )
+{
+    LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
+    const BYTE* ip = (const BYTE*) source;
+    const BYTE* anchor = ip;
+    const BYTE* const iend = ip + inputSize;
+    const BYTE* const mflimit = iend - MFLIMIT;
+    const BYTE* const matchlimit = (iend - LASTLITERALS);
+
+    BYTE* op = (BYTE*) dest;
+    BYTE* const oend = op + maxOutputSize;
+
+    int   ml, ml2, ml3, ml0;
+    const BYTE* ref=NULL;
+    const BYTE* start2=NULL;
+    const BYTE* ref2=NULL;
+    const BYTE* start3=NULL;
+    const BYTE* ref3=NULL;
+    const BYTE* start0;
+    const BYTE* ref0;
+
+
+    // Ensure blocks follow each other
+    if (ip != ctx->end) return 0;
+    ctx->end += inputSize;
+
+    ip++;
+
+    // Main Loop
+    while (ip < mflimit)
+    {
+        ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref));
+        if (!ml) { ip++; continue; }
+
+        // saved, in case we would skip too much
+        start0 = ip;
+        ref0 = ref;
+        ml0 = ml;
+
+_Search2:
+        if (ip+ml < mflimit)
+            ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2);
+        else ml2 = ml;
+
+        if (ml2 == ml)  // No better match
+        {
+            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
+            continue;
+        }
+
+        if (start0 < ip)
+        {
+            if (start2 < ip + ml0)   // empirical
+            {
+                ip = start0;
+                ref = ref0;
+                ml = ml0;
+            }
+        }
+
+        // Here, start0==ip
+        if ((start2 - ip) < 3)   // First Match too small : removed
+        {
+            ml = ml2;
+            ip = start2;
+            ref =ref2;
+            goto _Search2;
+        }
+
+_Search3:
+        // Currently we have :
+        // ml2 > ml1, and
+        // ip1+3 <= ip2 (usually < ip1+ml1)
+        if ((start2 - ip) < OPTIMAL_ML)
+        {
+            int correction;
+            int new_ml = ml;
+            if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
+            if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
+            correction = new_ml - (int)(start2 - ip);
+            if (correction > 0)
+            {
+                start2 += correction;
+                ref2 += correction;
+                ml2 -= correction;
+            }
+        }
+        // Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18)
+
+        if (start2 + ml2 < mflimit)
+            ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3);
+        else ml3 = ml2;
+
+        if (ml3 == ml2) // No better match : 2 sequences to encode
+        {
+            // ip & ref are known; Now for ml
+            if (start2 < ip+ml)  ml = (int)(start2 - ip);
+            // Now, encode 2 sequences
+            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
+            ip = start2;
+            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
+            continue;
+        }
+
+        if (start3 < ip+ml+3) // Not enough space for match 2 : remove it
+        {
+            if (start3 >= (ip+ml)) // can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1
+            {
+                if (start2 < ip+ml)
+                {
+                    int correction = (int)(ip+ml - start2);
+                    start2 += correction;
+                    ref2 += correction;
+                    ml2 -= correction;
+                    if (ml2 < MINMATCH)
+                    {
+                        start2 = start3;
+                        ref2 = ref3;
+                        ml2 = ml3;
+                    }
+                }
+
+                if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
+                ip  = start3;
+                ref = ref3;
+                ml  = ml3;
+
+                start0 = start2;
+                ref0 = ref2;
+                ml0 = ml2;
+                goto _Search2;
+            }
+
+            start2 = start3;
+            ref2 = ref3;
+            ml2 = ml3;
+            goto _Search3;
+        }
+
+        // OK, now we have 3 ascending matches; let's write at least the first one
+        // ip & ref are known; Now for ml
+        if (start2 < ip+ml)
+        {
+            if ((start2 - ip) < (int)ML_MASK)
+            {
+                int correction;
+                if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
+                if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
+                correction = ml - (int)(start2 - ip);
+                if (correction > 0)
+                {
+                    start2 += correction;
+                    ref2 += correction;
+                    ml2 -= correction;
+                }
+            }
+            else
+            {
+                ml = (int)(start2 - ip);
+            }
+        }
+        if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
+
+        ip = start2;
+        ref = ref2;
+        ml = ml2;
+
+        start2 = start3;
+        ref2 = ref3;
+        ml2 = ml3;
+
+        goto _Search3;
+
+    }
+
+    // Encode Last Literals
+    {
+        int lastRun = (int)(iend - anchor);
+        if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0;  // Check output limit
+        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } 
+        else *op++ = (BYTE)(lastRun<<ML_BITS);
+        memcpy(op, anchor, iend - anchor);
+        op += iend-anchor;
+    } 
+
+    // End
+    return (int) (((char*)op)-dest);
+}
+
+
+int LZ4_compressHC(const char* source, char* dest, int inputSize)
+{
+    void* ctx = LZ4_createHC(source);
+    int result;
+    if (ctx==NULL) return 0;
+
+    result = LZ4HC_compress_generic (ctx, source, dest, inputSize, 0, noLimit);
+
+    LZ4_freeHC(ctx);
+    return result;
+}
+
+int LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize)
+{
+    return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, noLimit);
+}
+
+
+int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
+{
+    void* ctx = LZ4_createHC(source);
+    int result;
+    if (ctx==NULL) return 0;
+
+    result = LZ4HC_compress_generic (ctx, source, dest, inputSize, maxOutputSize, limitedOutput);
+
+    LZ4_freeHC(ctx);
+    return result;
+}
+
+int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize)
+{
+    return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, limitedOutput);
+}
+
diff --git a/mkfs.ubifs/lz4/lz4hc.h b/mkfs.ubifs/lz4/lz4hc.h
new file mode 100644
index 0000000..f3fd954
--- /dev/null
+++ b/mkfs.ubifs/lz4/lz4hc.h
@@ -0,0 +1,111 @@
+/*
+   LZ4 HC - High Compression Mode of LZ4
+   Header File
+   Copyright (C) 2011-2013, Yann Collet.
+   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+       * Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+       * Redistributions in binary form must reproduce the above
+   copyright notice, this list of conditions and the following disclaimer
+   in the documentation and/or other materials provided with the
+   distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+   You can contact the author at :
+   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
+   - LZ4 source repository : http://code.google.com/p/lz4/
+*/
+#pragma once
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+int LZ4_compressHC (const char* source, char* dest, int inputSize);
+/*
+LZ4_compressHC :
+    return : the number of bytes in compressed buffer dest
+             or 0 if compression fails.
+    note : destination buffer must be already allocated. 
+        To avoid any problem, size it to handle worst cases situations (input data not compressible)
+        Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h")
+*/
+
+int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
+/*
+LZ4_compress_limitedOutput() :
+    Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
+    If it cannot achieve it, compression will stop, and result of the function will be zero.
+    This function never writes outside of provided output buffer.
+
+    inputSize  : Max supported value is 1 GB
+    maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated)
+    return : the number of output bytes written in buffer 'dest'
+             or 0 if compression fails.
+*/
+
+
+/* Note :
+Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license)
+*/
+
+
+/* Advanced Functions */
+
+void* LZ4_createHC (const char* inputBuffer);
+int   LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize);
+int   LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize);
+char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
+int   LZ4_freeHC (void* LZ4HC_Data);
+
+/* 
+These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks.
+In order to achieve this, it is necessary to start creating the LZ4HC Data Structure, thanks to the function :
+
+void* LZ4_createHC (const char* inputBuffer);
+The result of the function is the (void*) pointer on the LZ4HC Data Structure.
+This pointer will be needed in all other functions.
+If the pointer returned is NULL, then the allocation has failed, and compression must be aborted.
+The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer.
+The input buffer must be already allocated, and size at least 192KB.
+'inputBuffer' will also be the 'const char* source' of the first block.
+
+All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'.
+To compress each block, use either LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue().
+Their behavior are identical to LZ4_compressHC() or LZ4_compressHC_limitedOutput(), 
+but require the LZ4HC Data Structure as their first argument, and check that each block starts right after the previous one.
+If next block does not begin immediately after the previous one, the compression will fail (return 0).
+
+When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : 
+char* LZ4_slideInputBufferHC(void* LZ4HC_Data);
+must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer.
+Note that, for this function to work properly, minimum size of an input buffer must be 192KB.
+==> The memory position where the next input data block must start is provided as the result of the function.
+
+Compression can then resume, using LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(), as usual.
+
+When compression is completed, a call to LZ4_freeHC() will release the memory used by the LZ4HC Data Structure.
+*/
+
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/mkfs.ubifs/mkfs.ubifs.c b/mkfs.ubifs/mkfs.ubifs.c
index f9977bc..b68b0bd 100644
--- a/mkfs.ubifs/mkfs.ubifs.c
+++ b/mkfs.ubifs/mkfs.ubifs.c
@@ -179,11 +179,11 @@ static const char *helptext =
 "-o, --output=FILE        output to FILE\n"
 "-j, --jrn-size=SIZE      journal size\n"
 "-R, --reserved=SIZE      how much space should be reserved for the super-user\n"
-"-x, --compr=TYPE         compression type - \"lzo\", \"favor_lzo\", \"zlib\" or\n"
-"                         \"none\" (default: \"lzo\")\n"
-"-X, --favor-percent      may only be used with favor LZO compression and defines\n"
-"                         how many percent better zlib should compress to make\n"
-"                         mkfs.ubifs use zlib instead of LZO (default 20%)\n"
+"-x, --compr=TYPE         compression type - \"lzo\", \"favor_lzo\", \"lz4hc\",\n"
+"                          \"favor_lz4hc\", \"zlib\" or \"none\" (default: \"lzo\")\n"
+"-X, --favor-percent      may only be used with favor LZO or LZ4HC compression and\n"
+"                         defines how many percent better zlib should compress to\n"
+"                         make mkfs.ubifs use zlib instead of LZO/LZ4HC (default 20%)\n"
 "-f, --fanout=NUM         fanout NUM (default: 8)\n"
 "-F, --space-fixup        file-system free space has to be fixed up on first mount\n"
 "                         (requires kernel version 3.0 or greater)\n"
@@ -201,14 +201,15 @@ static const char *helptext =
 "-h, --help               display this help text\n\n"
 "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n"
 "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n"
-"If you specify \"lzo\" or \"zlib\" compressors, mkfs.ubifs will use this compressor\n"
-"for all data. The \"none\" disables any data compression. The \"favor_lzo\" is not\n"
-"really a separate compressor. It is just a method of combining \"lzo\" and \"zlib\"\n"
-"compressors. Namely, mkfs.ubifs tries to compress data with both \"lzo\" and \"zlib\"\n"
-"compressors, then it compares which compressor is better. If \"zlib\" compresses 20\n"
-"or more percent better than \"lzo\", mkfs.ubifs chooses \"lzo\", otherwise it chooses\n"
-"\"zlib\". The \"--favor-percent\" may specify arbitrary threshold instead of the\n"
-"default 20%.\n\n"
+"If you specify \"lz4hc\", \"lzo\" or \"zlib\" compressors, mkfs.ubifs will use this\n"
+"compressor for all data. The \"none\" disables any data compression. The \"favor_lzo\"\n"
+"or \"favor_lz4hc\" are not really separate compressors. They are just a method of\n"
+"combining \"lzo\" and \"zlib\" or \"lz4hc\" and \"zlib\" compressors.\n"
+"Namely, mkfs.ubifs tries to compress data with both compressors specified,\n"
+"then it compares which compressor is better. If \"zlib\" compresses 20\n"
+"or more percent better than the alternative, mkfs.ubifs chooses \"zlib\", otherwise\n"
+"the alternative is chosen. The \"--favor-percent\" may specify arbitrary threshold\n"
+"instead of the default 20%.\n\n"
 "The -F parameter is used to set the \"fix up free space\" flag in the superblock,\n"
 "which forces UBIFS to \"fixup\" all the free space which it is going to use. This\n"
 "option is useful to work-around the problem of double free space programming: if the\n"
@@ -596,8 +597,12 @@ static int get_options(int argc, char**argv)
 		case 'x':
 			if (strcmp(optarg, "favor_lzo") == 0)
 				c->favor_lzo = 1;
+			else if (strcmp(optarg, "favor_lz4hc") == 0)
+				c->favor_lz4hc = 1;
 			else if (strcmp(optarg, "zlib") == 0)
 				c->default_compr = UBIFS_COMPR_ZLIB;
+			else if (strcmp(optarg, "lz4hc") == 0)
+				c->default_compr = UBIFS_COMPR_LZ4HC;
 			else if (strcmp(optarg, "none") == 0)
 				c->default_compr = UBIFS_COMPR_NONE;
 			else if (strcmp(optarg, "lzo") != 0)
@@ -607,7 +612,7 @@ static int get_options(int argc, char**argv)
 			c->favor_percent = strtol(optarg, &endp, 0);
 			if (*endp != '\0' || endp == optarg ||
 			    c->favor_percent <= 0 || c->favor_percent >= 100)
-				return err_msg("bad favor LZO percent '%s'",
+				return err_msg("bad favor percent '%s'",
 					       optarg);
 			break;
 		case 'j':
diff --git a/mkfs.ubifs/ubifs-media.h b/mkfs.ubifs/ubifs-media.h
index fe62d0e..96b8500 100644
--- a/mkfs.ubifs/ubifs-media.h
+++ b/mkfs.ubifs/ubifs-media.h
@@ -296,6 +296,7 @@ enum {
  *
  * UBIFS_COMPR_NONE: no compression
  * UBIFS_COMPR_LZO: LZO compression
+ * UBIFS_COMPR_LZ4HC: LZ4HC compression
  * UBIFS_COMPR_ZLIB: ZLIB compression
  * UBIFS_COMPR_TYPES_CNT: count of supported compression types
  */
@@ -303,6 +304,7 @@ enum {
 	UBIFS_COMPR_NONE,
 	UBIFS_COMPR_LZO,
 	UBIFS_COMPR_ZLIB,
+	UBIFS_COMPR_LZ4HC,
 	UBIFS_COMPR_TYPES_CNT,
 };
 
diff --git a/mkfs.ubifs/ubifs.h b/mkfs.ubifs/ubifs.h
index 434b651..87f944a 100644
--- a/mkfs.ubifs/ubifs.h
+++ b/mkfs.ubifs/ubifs.h
@@ -276,6 +276,7 @@ struct ubifs_znode
  * @main_first: first LEB of the main area
  * @default_compr: default compression type
  * @favor_lzo: favor LZO compression method
+ * @favor_lz4hc: favor LZ4HC compression method
  * @favor_percent: lzo vs. zlib threshold used in case favor LZO
  *
  * @key_hash_type: type of the key hash
@@ -354,6 +355,7 @@ struct ubifs_info
 	int main_first;
 	int default_compr;
 	int favor_lzo;
+	int favor_lz4hc;
 	int favor_percent;
 
 	uint8_t key_hash_type;
-- 
1.7.10.4



From annulen at yandex.ru  Sat Oct  5 07:53:23 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Sat, 05 Oct 2013 15:53:23 +0400
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
Message-ID: <106341380974003@web15m.yandex.ru>



05.10.2013, 10:53, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
> Brent et all,
>
> I was bored last night and while following the thread on the lz4hc
> compression for ubifs got my attention so I decided to give a go at
> implementing in. Below you can find a patch which does just that.
>
> An lz4hc and favor_lz4hc compr type, they mimick lzo and favor_lzo
> but use lz4hc instead of lzo.
>
> In order to use lz4hc I included 3 files from the lz4 project since
> lz4 is not yet available in a conventient modular form (suggestions
> to fix this are welcome).
>
> In the meantime I saw however that Brent was also considering adding
> lz4hc support mkfs.ubifs so I'm making a v0 zero post either to serve
> as input for review comment (mainly on handling the lz4 dependency)
> and then I'll take care of cleaning up and testing it myself, or just
> to serve as some reference to the implementation of Brent, let me know
> of you want some polishing up on this version or are already in an
> advanced phase of a solution of yourself.
>
> (Yes, it's called v0, it's still untested but I would like input on
> the lz4 dependency handling and the extension of the options, or
> do we see something feasible where we contain lzo/lz4hc and zlib on
> the fly, suggestions welcome).
>
> my 2 cents
> E.

Thank you very much!

Unfortunately, your patch does not apply cleanly. I've tried mtd-utils
master and v1.5.0, and got rejects in both cases.

-- 
Regards,
Konstantin


From eliedebrauwer at gmail.com  Sat Oct  5 08:56:19 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Sat, 5 Oct 2013 14:56:19 +0200
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <106341380974003@web15m.yandex.ru>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
 <106341380974003@web15m.yandex.ru>
Message-ID: <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>

On Sat, Oct 5, 2013 at 1:53 PM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 05.10.2013, 10:53, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>> Brent et all,
>>
>> I was bored last night and while following the thread on the lz4hc
>> compression for ubifs got my attention so I decided to give a go at
>> implementing in. Below you can find a patch which does just that.
>>
>> An lz4hc and favor_lz4hc compr type, they mimick lzo and favor_lzo
>> but use lz4hc instead of lzo.
>>
>> In order to use lz4hc I included 3 files from the lz4 project since
>> lz4 is not yet available in a conventient modular form (suggestions
>> to fix this are welcome).
>>
>> In the meantime I saw however that Brent was also considering adding
>> lz4hc support mkfs.ubifs so I'm making a v0 zero post either to serve
>> as input for review comment (mainly on handling the lz4 dependency)
>> and then I'll take care of cleaning up and testing it myself, or just
>> to serve as some reference to the implementation of Brent, let me know
>> of you want some polishing up on this version or are already in an
>> advanced phase of a solution of yourself.
>>
>> (Yes, it's called v0, it's still untested but I would like input on
>> the lz4 dependency handling and the extension of the options, or
>> do we see something feasible where we contain lzo/lz4hc and zlib on
>> the fly, suggestions welcome).
>>
>> my 2 cents
>> E.
>
> Thank you very much!
>
> Unfortunately, your patch does not apply cleanly. I've tried mtd-utils
> master and v1.5.0, and got rejects in both cases.
>

That's odd, yesterday I started by cloning mtd-utils.git and when I
try to repeat my own steps and apply my patch it does seem to work.

edb at lapelidb:/tmp$ mkdir l
edb at lapelidb:/tmp$ cd l/
edb at lapelidb:/tmp/l$ git clone -q git://git.infradead.org/mtd-utils.git
edb at lapelidb:/tmp/l$ cd mtd-utils/
edb at lapelidb:/tmp/l/mtd-utils$ patch -p1 <
/tmp/0001-mkfs.ubifs-Add-support-for-lz4hc-compressor-in-mkfs..patch
patching file Makefile
patching file mkfs.ubifs/README
patching file mkfs.ubifs/compr.c
patching file mkfs.ubifs/compr.h
patching file mkfs.ubifs/lz4/lz4.h
patching file mkfs.ubifs/lz4/lz4hc.c
patching file mkfs.ubifs/lz4/lz4hc.h
patching file mkfs.ubifs/mkfs.ubifs.c
patching file mkfs.ubifs/ubifs-media.h
patching file mkfs.ubifs/ubifs.h
edb at lapelidb:/tmp/l/mtd-utils$

The only thing I can imagine is that I started from a wrong repository
... any pointers ?

gr
E.



-- 
Elie De Brauwer


From annulen at yandex.ru  Sat Oct  5 09:24:40 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Sat, 05 Oct 2013 17:24:40 +0400
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
 <106341380974003@web15m.yandex.ru>
 <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>
Message-ID: <183051380979480@web15m.yandex.ru>



05.10.2013, 16:56, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
> That's odd, yesterday I started by cloning mtd-utils.git and when I
> try to repeat my own steps and apply my patch it does seem to work.

I've figured it out: you've included patch into the mail instead of attaching
it as a file, so I copied it, and tab characters got lost. patch -p1 -l 
works successfully.

-- 
Regards,
Konstantin


From annulen at yandex.ru  Sat Oct  5 09:51:08 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Sat, 05 Oct 2013 17:51:08 +0400
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <183051380979480@web15m.yandex.ru>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
 <106341380974003@web15m.yandex.ru>
 <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>
 <183051380979480@web15m.yandex.ru>
Message-ID: <201501380981068@web15m.yandex.ru>



05.10.2013, 17:25, "Konstantin Tokarev" <annulen at yandex.ru>:
> 05.10.2013, 16:56, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>
>> ?That's odd, yesterday I started by cloning mtd-utils.git and when I
>> ?try to repeat my own steps and apply my patch it does seem to work.
>
> I've figured it out: you've included patch into the mail instead of attaching
> it as a file, so I copied it, and tab characters got lost. patch -p1 -l
> works successfully.

When trying to compress my rootfs, I got message "32866 compression errors occurred".
Resulting image is much larger than LZO one (133M for lz4hc, 86M for lzo, 79M for zlib)

-- 
Regards,
Konstantin


From annulen at yandex.ru  Sat Oct  5 10:17:31 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Sat, 05 Oct 2013 18:17:31 +0400
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <201501380981068@web15m.yandex.ru>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
 <106341380974003@web15m.yandex.ru>
 <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>
 <183051380979480@web15m.yandex.ru> <201501380981068@web15m.yandex.ru>
Message-ID: <8451380982651@web23h.yandex.ru>



05.10.2013, 17:52, "Konstantin Tokarev" <annulen at yandex.ru>:
> 05.10.2013, 17:25, "Konstantin Tokarev" <annulen at yandex.ru>:
>
>> ?05.10.2013, 16:56, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>>> ??That's odd, yesterday I started by cloning mtd-utils.git and when I
>>> ??try to repeat my own steps and apply my patch it does seem to work.
>> ?I've figured it out: you've included patch into the mail instead of attaching
>> ?it as a file, so I copied it, and tab characters got lost. patch -p1 -l
>> ?works successfully.
>
> When trying to compress my rootfs, I got message "32866 compression errors occurred".
> Resulting image is much larger than LZO one (133M for lz4hc, 86M for lzo, 79M for zlib)

The next patch over your patch fixes the issue:

diff --git a/mkfs.ubifs/compr.c b/mkfs.ubifs/compr.c
index 2030042..65c7dbe 100644
--- a/mkfs.ubifs/compr.c
+++ b/mkfs.ubifs/compr.c
@@ -109,9 +109,10 @@ static int lz4hc_compress(void *in_buf, size_t in_len, void *out_buf,
            size_t *out_len)
 {
    int ret;
-   ret = LZ4_compressHC_limitedOutput(in_buf, out_buf, in_len, *out_len);
+   ret = LZ4_compressHC(in_buf, out_buf, in_len);
+   *out_len = ret;

-   if (ret != 0) {
+   if (ret == 0) {
        errcnt += 1;
        return -1;
    }


I've replaced LZ4_compressHC_limitedOutput with LZ4_compressHC to match lzo_compress logic which changes out_len instead of limiting it. No errors are reported now. However, result is still larger than LZO (93M).



-- 
Regards,
Konstantin


From eliedebrauwer at gmail.com  Sat Oct  5 10:17:45 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Sat, 5 Oct 2013 16:17:45 +0200
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <201501380981068@web15m.yandex.ru>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
 <106341380974003@web15m.yandex.ru>
 <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>
 <183051380979480@web15m.yandex.ru>
 <201501380981068@web15m.yandex.ru>
Message-ID: <CAGWqfigxKOLsaQvbPWNt7AbmOdCmeUSxkFv8naJt1Hn5bo6uUQ@mail.gmail.com>

On Sat, Oct 5, 2013 at 3:51 PM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 05.10.2013, 17:25, "Konstantin Tokarev" <annulen at yandex.ru>:
>> 05.10.2013, 16:56, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>>
>>>  That's odd, yesterday I started by cloning mtd-utils.git and when I
>>>  try to repeat my own steps and apply my patch it does seem to work.
>>
>> I've figured it out: you've included patch into the mail instead of attaching
>> it as a file, so I copied it, and tab characters got lost. patch -p1 -l
>> works successfully.
>
> When trying to compress my rootfs, I got message "32866 compression errors occurred".
> Resulting image is much larger than LZO one (133M for lz4hc, 86M for lzo, 79M for zlib)
>


That only proofs I wasn't lying when I wrote this morning that my code
was fully untested. I had some time to do some testing and if you
apply the following, (cummulative to my last patch) it should also
work.

diff --git a/mkfs.ubifs/compr.c b/mkfs.ubifs/compr.c
index d9886b4..0900653 100644
--- a/mkfs.ubifs/compr.c
+++ b/mkfs.ubifs/compr.c
@@ -110,11 +110,12 @@ static int lz4hc_compress(void *in_buf, size_t in_len, voi
 {
        int ret;
        ret = LZ4_compressHC_limitedOutput(in_buf, out_buf, in_len, *out_len);
-
-       if (ret != 0) {
+       if (ret == 0) {
                errcnt += 1;
                return -1;
        }
+       else
+               *out_len = ret;

        return 0;
 }

I get the following (preliminary) results:

edb at lapelidb:/tmp$ ls -hal imag*
-rw-r--r-- 1 edb  edb  28M Oct  5 16:12 imag.lz4hc
-rw-r--r-- 1 root root 25M Oct  5 16:09 imag.lzo
-rw-r--r-- 1 root root 43M Oct  5 16:11 imag.none
-rw-r--r-- 1 root root 22M Oct  5 16:11 imag.zlib

gr
E.



-- 
Elie De Brauwer


From eliedebrauwer at gmail.com  Sat Oct  5 10:25:07 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Sat, 5 Oct 2013 16:25:07 +0200
Subject: [PATCH v0] mkfs.ubifs: Add support for lz4hc compressor in
 mkfs.ubifs
In-Reply-To: <8451380982651@web23h.yandex.ru>
References: <1380956001-6122-1-git-send-email-eliedebrauwer@gmail.com>
 <106341380974003@web15m.yandex.ru>
 <CAGWqfijZSPZrQt762HmgGj-GJjbbRbTgmNb-OSFtL1OVSdOeNQ@mail.gmail.com>
 <183051380979480@web15m.yandex.ru>
 <201501380981068@web15m.yandex.ru> <8451380982651@web23h.yandex.ru>
Message-ID: <CAGWqfig=ZzkD4MyW2PD=iw6NBdd+nN6S+NXd30toMObiuroFPg@mail.gmail.com>

On Sat, Oct 5, 2013 at 4:17 PM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 05.10.2013, 17:52, "Konstantin Tokarev" <annulen at yandex.ru>:
>> 05.10.2013, 17:25, "Konstantin Tokarev" <annulen at yandex.ru>:
>>
>>>  05.10.2013, 16:56, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>>>>   That's odd, yesterday I started by cloning mtd-utils.git and when I
>>>>   try to repeat my own steps and apply my patch it does seem to work.
>>>  I've figured it out: you've included patch into the mail instead of attaching
>>>  it as a file, so I copied it, and tab characters got lost. patch -p1 -l
>>>  works successfully.
>>
>> When trying to compress my rootfs, I got message "32866 compression errors occurred".
>> Resulting image is much larger than LZO one (133M for lz4hc, 86M for lzo, 79M for zlib)
>
> The next patch over your patch fixes the issue:
>
> diff --git a/mkfs.ubifs/compr.c b/mkfs.ubifs/compr.c
> index 2030042..65c7dbe 100644
> --- a/mkfs.ubifs/compr.c
> +++ b/mkfs.ubifs/compr.c
> @@ -109,9 +109,10 @@ static int lz4hc_compress(void *in_buf, size_t in_len, void *out_buf,
>             size_t *out_len)
>  {
>     int ret;
> -   ret = LZ4_compressHC_limitedOutput(in_buf, out_buf, in_len, *out_len);
> +   ret = LZ4_compressHC(in_buf, out_buf, in_len);
> +   *out_len = ret;
>
> -   if (ret != 0) {
> +   if (ret == 0) {
>         errcnt += 1;
>         return -1;
>     }
>
>
> I've replaced LZ4_compressHC_limitedOutput with LZ4_compressHC to match lzo_compress logic which changes out_len instead of limiting it. No errors are reported now. However, result is still larger than LZO (93M).
>
>

Oops, guessed our e-mails crossed each-other, the reason why I
initially choose limitedOutput is because compressHC will assume the
output buffer is large enough (which means it could potentially
outgrow the input buffer in size, it seemed safer to use the
limitedOutput option now rather than to introduce a potential buffer
overflow).

But apparently our findings are the same, lz4hc also produces a
slightly larger resulting binary, but it is the fastet one (on my x86
laptop):

edb at lapelidb:/tmp/l/mtd-utils$ time sudo mkfs.ubifs/mkfs.ubifs  -x
none -m 2048 -e 126976 -c 744 -d /tmp/rootfs/ /tmp/imag.zlib

real 0m0.452s
user 0m0.108s
sys 0m0.044s
edb at lapelidb:/tmp/l/mtd-utils$ time sudo mkfs.ubifs/mkfs.ubifs  -x
lz4hc -m 2048 -e 126976 -c 744 -d /tmp/rootfs/ /tmp/imag.lz4hc

real 0m0.805s
user 0m0.768s
sys 0m0.032s
edb at lapelidb:/tmp/l/mtd-utils$ time sudo mkfs.ubifs/mkfs.ubifs  -x
zlib -m 2048 -e 126976 -c 744 -d /tmp/rootfs/ /tmp/imag.zlib

real 0m1.834s
user 0m1.792s
sys 0m0.036s
edb at lapelidb:/tmp/l/mtd-utils$ time sudo mkfs.ubifs/mkfs.ubifs  -x lzo
-m 2048 -e 126976 -c 744 -d /tmp/rootfs/ /tmp/imag.lzo

real 0m3.341s
user 0m3.296s
sys 0m0.044s

But it's at the decompression side that the real benefit probably lies
(as in flash performance vs decompression speed).

my 2 cents
E.





-- 
Elie De Brauwer


From eliedebrauwer at gmail.com  Sat Oct  5 10:48:04 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Sat, 5 Oct 2013 16:48:04 +0200
Subject: [PATCH v0.5] mtd-utils: mkfs.ubifs: Add support for LZ4HC compression
Message-ID: <CAGWqfihkGT5wWDoFGTtBHK31+Fvav8if6iy_jFJ7io1H_wktFA@mail.gmail.com>

All,

After some time to do some testing this is a second version of the
same patch. Now lz4hc gets actually used.  However at this moment in
time only improvement in terms of cpu time is seen, but lz4hc in this
context seems to behave worse than LZO, on my local system:

-rw-r--r-- 1 edb  edb  28M Oct  5 16:22 imag.lz4hc
-rw-r--r-- 1 root root 25M Oct  5 16:22 imag.lzo
-rw-r--r-- 1 root root 43M Oct  5 16:11 imag.none
-rw-r--r-- 1 root root 22M Oct  5 16:30 imag.zlib

The only thing which comes immediately to mind is that due to the size
of the chunks (in my case large block being compressed is 4k) lz4hc
isn't starting to pay off ..

my 2 cents
E.

-- 
Elie De Brauwer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mtd-utils-mkfs.ubifs-Add-support-for-LZ4HC-compressi.patch
Type: application/octet-stream
Size: 53887 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131005/4812e08e/attachment-0001.obj>

From annulen at yandex.ru  Sat Oct  5 14:23:02 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Sat, 05 Oct 2013 22:23:02 +0400
Subject: [PATCH v0.5] mtd-utils: mkfs.ubifs: Add support for LZ4HC
 compression
In-Reply-To: <CAGWqfihkGT5wWDoFGTtBHK31+Fvav8if6iy_jFJ7io1H_wktFA@mail.gmail.com>
References: <CAGWqfihkGT5wWDoFGTtBHK31+Fvav8if6iy_jFJ7io1H_wktFA@mail.gmail.com>
Message-ID: <165301380997382@web12j.yandex.ru>



05.10.2013, 18:48, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
> All,
>
> After some time to do some testing this is a second version of the
> same patch. Now lz4hc gets actually used. ?However at this moment in
> time only improvement in terms of cpu time is seen, but lz4hc in this
> context seems to behave worse than LZO, on my local system:
>
> -rw-r--r-- 1 edb ?edb ?28M Oct ?5 16:22 imag.lz4hc
> -rw-r--r-- 1 root root 25M Oct ?5 16:22 imag.lzo
> -rw-r--r-- 1 root root 43M Oct ?5 16:11 imag.none
> -rw-r--r-- 1 root root 22M Oct ?5 16:30 imag.zlib
>
> The only thing which comes immediately to mind is that due to the size
> of the chunks (in my case large block being compressed is 4k) lz4hc
> isn't starting to pay off ..

Looks like it might be useful to have mixed lz4hc/lzo mode - lz4hc is faster,
lzo provides better ratio, and both don't use additional memory for decompression.
I did no speed benchmarks yet though.

It also might be that lz4 has tuning parameters which may be useful for rootfs
compression in case when most of files are not modified most of the times, i.e.
trade compression time to space efficiency while keeping decompression speed.

-- 
Regards,
Konstantin


From annulen at yandex.ru  Sun Oct  6 11:25:18 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Sun, 06 Oct 2013 19:25:18 +0400
Subject: [PATCH v0.5] mtd-utils: mkfs.ubifs: Add support for LZ4HC
 compression
In-Reply-To: <165301380997382@web12j.yandex.ru>
References: <CAGWqfihkGT5wWDoFGTtBHK31+Fvav8if6iy_jFJ7io1H_wktFA@mail.gmail.com>
 <165301380997382@web12j.yandex.ru>
Message-ID: <47881381073118@web4j.yandex.ru>



05.10.2013, 22:24, "Konstantin Tokarev" <annulen at yandex.ru>:
> 05.10.2013, 18:48, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>
>> ?All,
>>
>> ?After some time to do some testing this is a second version of the
>> ?same patch. Now lz4hc gets actually used. ?However at this moment in
>> ?time only improvement in terms of cpu time is seen, but lz4hc in this
>> ?context seems to behave worse than LZO, on my local system:
>>
>> ?-rw-r--r-- 1 edb ?edb ?28M Oct ?5 16:22 imag.lz4hc
>> ?-rw-r--r-- 1 root root 25M Oct ?5 16:22 imag.lzo
>> ?-rw-r--r-- 1 root root 43M Oct ?5 16:11 imag.none
>> ?-rw-r--r-- 1 root root 22M Oct ?5 16:30 imag.zlib
>>
>> ?The only thing which comes immediately to mind is that due to the size
>> ?of the chunks (in my case large block being compressed is 4k) lz4hc
>> ?isn't starting to pay off ..
>
> Looks like it might be useful to have mixed lz4hc/lzo mode - lz4hc is faster,
> lzo provides better ratio, and both don't use additional memory for decompression.
> I did no speed benchmarks yet though.
>
> It also might be that lz4 has tuning parameters which may be useful for rootfs
> compression in case when most of files are not modified most of the times, i.e.
> trade compression time to space efficiency while keeping decompression speed.

In attached patch I've replaced "favor lz4hc" mode with lz4hc/lzo mix, depending
purely on which algorithm gives smaller size for the block. In my case it allowed
to get slightly smaller image size than lzo (27564 blocks were compressed with lzo
and 1054 - with lz4hc).

-- 
Regards,
Konstantin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-LZ4HC-LZO-hybrid-compression.patch
Type: text/x-diff
Size: 2170 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131006/0b27f59a/attachment.bin>

From wkuzma at franciszkanie.pl  Sun Oct  6 01:54:34 2013
From: wkuzma at franciszkanie.pl (elena.g2)
Date: Sun, 6 Oct 2013 07:54:34 +0200
Subject: [RandText,uborka_temi: Specified TextBlock does not exists!]
Message-ID: <45728F2CE21841E688424B440D574847@hterh>

[RandText,uborka-text: Specified TextBlock does not exists!]


From eliedebrauwer at gmail.com  Mon Oct  7 02:34:34 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Mon, 7 Oct 2013 08:34:34 +0200
Subject: [PATCH v0.5] mtd-utils: mkfs.ubifs: Add support for LZ4HC
 compression
In-Reply-To: <47881381073118@web4j.yandex.ru>
References: <CAGWqfihkGT5wWDoFGTtBHK31+Fvav8if6iy_jFJ7io1H_wktFA@mail.gmail.com>
 <165301380997382@web12j.yandex.ru> <47881381073118@web4j.yandex.ru>
Message-ID: <CAGWqfihRaNSs-uc9utTPaNPHU__KTS5saxgc2xUrkw5sYy4kkQ@mail.gmail.com>

Konstantin,

Sounds interesting, I'll integrate this into a next version of the
patch. Perhaps it make sense just to replace favor_lzo and favor_lz4hc
into something generic like favor_COMPR1_COMPR2 where COMPR2 gets
chosen if it is more than favor-percent better than COMPR1. Even
though today you're probably use lzo/zlib to optimise for size at a
reasonable cost of some speed  while you're probably use lzo/lz4hc if
you want to optimise for speed at a reasonable cost of size, but that
probably makes it more extensible in the future. Does this sound
reasonable ?

my 2 cents
E.


On Sun, Oct 6, 2013 at 5:25 PM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 05.10.2013, 22:24, "Konstantin Tokarev" <annulen at yandex.ru>:
>> 05.10.2013, 18:48, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
>>
>>>  All,
>>>
>>>  After some time to do some testing this is a second version of the
>>>  same patch. Now lz4hc gets actually used.  However at this moment in
>>>  time only improvement in terms of cpu time is seen, but lz4hc in this
>>>  context seems to behave worse than LZO, on my local system:
>>>
>>>  -rw-r--r-- 1 edb  edb  28M Oct  5 16:22 imag.lz4hc
>>>  -rw-r--r-- 1 root root 25M Oct  5 16:22 imag.lzo
>>>  -rw-r--r-- 1 root root 43M Oct  5 16:11 imag.none
>>>  -rw-r--r-- 1 root root 22M Oct  5 16:30 imag.zlib
>>>
>>>  The only thing which comes immediately to mind is that due to the size
>>>  of the chunks (in my case large block being compressed is 4k) lz4hc
>>>  isn't starting to pay off ..
>>
>> Looks like it might be useful to have mixed lz4hc/lzo mode - lz4hc is faster,
>> lzo provides better ratio, and both don't use additional memory for decompression.
>> I did no speed benchmarks yet though.
>>
>> It also might be that lz4 has tuning parameters which may be useful for rootfs
>> compression in case when most of files are not modified most of the times, i.e.
>> trade compression time to space efficiency while keeping decompression speed.
>
> In attached patch I've replaced "favor lz4hc" mode with lz4hc/lzo mix, depending
> purely on which algorithm gives smaller size for the block. In my case it allowed
> to get slightly smaller image size than lzo (27564 blocks were compressed with lzo
> and 1054 - with lz4hc).
>
> --
> Regards,
> Konstantin



-- 
Elie De Brauwer


From annulen at yandex.ru  Mon Oct  7 04:33:54 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Mon, 07 Oct 2013 12:33:54 +0400
Subject: [PATCH v0.5] mtd-utils: mkfs.ubifs: Add support for LZ4HC
 compression
In-Reply-To: <CAGWqfihRaNSs-uc9utTPaNPHU__KTS5saxgc2xUrkw5sYy4kkQ@mail.gmail.com>
References: <CAGWqfihkGT5wWDoFGTtBHK31+Fvav8if6iy_jFJ7io1H_wktFA@mail.gmail.com>
 <165301380997382@web12j.yandex.ru> <47881381073118@web4j.yandex.ru>
 <CAGWqfihRaNSs-uc9utTPaNPHU__KTS5saxgc2xUrkw5sYy4kkQ@mail.gmail.com>
Message-ID: <227411381134834@web27j.yandex.ru>



07.10.2013, 10:34, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
> Konstantin,
>
> Sounds interesting, I'll integrate this into a next version of the
> patch. Perhaps it make sense just to replace favor_lzo and favor_lz4hc
> into something generic like favor_COMPR1_COMPR2 where COMPR2 gets
> chosen if it is more than favor-percent better than COMPR1. Even
> though today you're probably use lzo/zlib to optimise for size at a
> reasonable cost of some speed ?while you're probably use lzo/lz4hc if
> you want to optimise for speed at a reasonable cost of size, but that
> probably makes it more extensible in the future. Does this sound
> reasonable ?

Yeah, that would be useful.

-- 
Regards,
Konstantin


From pekon at ti.com  Mon Oct  7 06:55:01 2013
From: pekon at ti.com (Pekon Gupta)
Date: Mon, 7 Oct 2013 16:25:01 +0530
Subject: [PATCH v2 0/4] optimize and clean-up of OMAP NAND and ELM driver
Message-ID: <1381143305-28617-1-git-send-email-pekon@ti.com>

*changes from v1 (minor)*
- rebased for newer version of previous patch-set
	[PATCH v7 0/6] mtd:nand:omap2: clean-up of supported ECC schemes
	http://lists.infradead.org/pipermail/linux-mtd/2013-October/048983.html
- code cleanup and formating updates

*original v1*
This patch series builds the base for adding support for newer H/W based ECC
schemes for NAND flash. This patch series 
- cleans-up redundant code among various
- optimizes ecc calculation and correction paths
- improves scalability and readability, for adding newer ecc-schemes in future.
This patch affects following data-paths: 
[PATCH 1/4] NAND chip->ecc.correct(): Detects and corrects ECC errors on read accesses.
[PATCH 2/4] NAND chip->ecc.calculate(): Calculates and fetches ECC syndrome from controller.
[PATCH 3/4] NAND chip->ecc.hwctl(): Configures H/W controller for Read/Write data acccesses.
[PATCH 4/4] ELM  add checks and updates code for scalability.

Pekon Gupta (4):
  mtd: nand: omap: optimized chip->ecc.correct() for H/W ECC schemes
  mtd: nand: omap: optimize chip->ecc.calculate() for H/W ECC schemes
  mtd: nand: omap: optimize chip->ecc.hwctl() for H/W ECC schemes
  mtd: devices: elm: add checks ELM H/W constrains, driver code cleanup

 drivers/mtd/devices/elm.c         | 122 ++++---
 drivers/mtd/nand/omap2.c          | 723 +++++++++++++-------------------------
 include/linux/platform_data/elm.h |   6 +-
 3 files changed, 325 insertions(+), 526 deletions(-)

-- 
1.8.1



From pekon at ti.com  Mon Oct  7 06:55:03 2013
From: pekon at ti.com (Pekon Gupta)
Date: Mon, 7 Oct 2013 16:25:03 +0530
Subject: [PATCH v2 2/4] mtd: nand: omap: optimize chip->ecc.calculate() for
 H/W ECC schemes
In-Reply-To: <1381143305-28617-1-git-send-email-pekon@ti.com>
References: <1381143305-28617-1-git-send-email-pekon@ti.com>
Message-ID: <1381143305-28617-3-git-send-email-pekon@ti.com>

chip->ecc.calculate() is used for calculating and fetching of ECC syndrome by
processing the data passed during Read/Write accesses.

All H/W based ECC schemes supported in omap2-nand driver use GPMC controller
to calculate ECC syndrome. But each BCHx_ECC scheme implements its own function
to process and fetch ECC syndrom from GPMC controller.

This patch tries to merges the common code for different BCHx_ECC schemes into
single omap_calculate_ecc_bch(), And adds schemes specific post-possessing
after fetching ECC-syndrome. This removes redundant code and adds scalability
for future ECC-schemes. This patch:
- [un-touched]	omap_calculate_ecc():		Used for HAM1_ECC
- [merged]	omap3_calculate_ecc_bch4():	Used for BCH4_HW_DETECTION_SW
- [merged]	omap3_calculate_ecc_bch8():	Used for BCH8_HW_DETECTION_SW
- [merged]	omap3_calculate_ecc_bch():	Used for BCH4_HW and BCH8_HW
- [new]		omap_calculate_ecc_bch():	Now used for all BCHx_ECC

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 245 ++++++++++++++++++-----------------------------
 1 file changed, 92 insertions(+), 153 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c10a767..f9e5a4d 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -151,7 +151,11 @@ 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
-
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
+static u8  bch4_polynomial[] = {0x28, 0x13, 0xcc, 0x39, 0x96, 0xac, 0x7f};
+static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
+				0x97, 0x79, 0xe5, 0x24, 0xb5};
+#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
@@ -950,9 +954,11 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 	u32 val;
 
 	val = readl(info->reg.gpmc_ecc_config);
-	if (((val >> ECC_CONFIG_CS_SHIFT)  & ~CS_MASK) != info->gpmc_cs)
+	if (((val >> 1) & 0x07) != info->gpmc_cs) {
+		pr_err("%s: invalid ECC configuration for chip-select=%d",
+				DRIVER_NAME, info->gpmc_cs);
 		return -EINVAL;
-
+	}
 	/* read ecc result */
 	val = readl(info->reg.gpmc_ecc1_result);
 	*ecc_code++ = val;          /* P128e, ..., P1e */
@@ -1141,172 +1147,105 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	/* Clear ecc and enable bits */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
-#endif
-
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
- * @mtd: MTD device structure
- * @dat: The pointer to data on which ecc is computed
- * @ecc_code: The ecc_code buffer
- */
-static int omap3_calculate_ecc_bch4(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, 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;
-}
 
 /**
- * omap3_calculate_ecc_bch8 - Generate 13 bytes of ECC bytes
- * @mtd: MTD device structure
- * @dat: The pointer to data on which ecc is computed
- * @ecc_code: The ecc_code buffer
- */
-static int omap3_calculate_ecc_bch8(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, 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;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-/**
- * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
+ * omap_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 calculating of 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)
+static int omap_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
+				    u_char *ecc_calc)
 {
 	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;
+	struct nand_chip *chip = mtd->priv;
+	enum omap_ecc ecc_opt = info->ecc_opt;
+	struct gpmc_nand_regs	*gpmc_regs = &info->reg;
+	u32 eccbytes = chip->ecc.bytes;
+	u_char *ecc_ptr;
+	u32 nsectors;
+	int i, val;
 
-	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);
+	val = readl(info->reg.gpmc_ecc_config);
+	if (((val >> 1) & 0x07) != info->gpmc_cs) {
+		pr_err("%s: invalid ECC configuration for chip-select=%d",
+				DRIVER_NAME, info->gpmc_cs);
+		return -EINVAL;
+	}
+	nsectors = ((readl(gpmc_regs->gpmc_ecc_config) >> 4) & 0x7) + 1;
 
 	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]);
+		ecc_ptr = ecc_calc;
+		switch (ecc_opt) {
+		case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+		case OMAP_ECC_BCH4_CODE_HW:
+			val = readl(gpmc_regs->gpmc_bch_result1[i]);
+			*(ecc_ptr++) = ((val >> 12) & 0xFF);
+			*(ecc_ptr++) = ((val >>  4) & 0xFF);
+			*(ecc_ptr)   = ((val >>  0) << 4) & 0xF0;
+			val = readl(gpmc_regs->gpmc_bch_result0[i]);
+			*(ecc_ptr)   = ((val >> 28) & 0x0F) | *(ecc_ptr);
+			ecc_ptr++;
+			*(ecc_ptr++) = ((val >> 20) & 0xFF);
+			*(ecc_ptr++) = ((val >> 12) & 0xFF);
+			*(ecc_ptr++) = ((val >>  4) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) << 4) & 0xF0;
+			break;
+		case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+		case OMAP_ECC_BCH8_CODE_HW:
+			val = readl(gpmc_regs->gpmc_bch_result3[i]);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result2[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result1[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			val = readl(gpmc_regs->gpmc_bch_result0[i]);
+			*(ecc_ptr++) = ((val >> 24) & 0xFF);
+			*(ecc_ptr++) = ((val >> 16) & 0xFF);
+			*(ecc_ptr++) = ((val >>  8) & 0xFF);
+			*(ecc_ptr++) = ((val >>  0) & 0xFF);
+			break;
+		default:
+			return -EINVAL;
 		}
-
-		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;
+		/* ECC scheme specific syndrome customizations */
+		switch (ecc_opt) {
+		case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+			for (i = 0; i < eccbytes; i++)
+				*(ecc_calc + i) = *(ecc_calc + i) ^
+							bch4_polynomial[i];
+			break;
+		case OMAP_ECC_BCH4_CODE_HW:
+			*(ecc_ptr++) = 0x00;
+			break;
+		case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+			for (i = 0; i < eccbytes; i++)
+				*(ecc_calc + i) = *(ecc_calc + i) ^
+							bch8_polynomial[i];
+			break;
+		case OMAP_ECC_BCH8_CODE_HW:
+			*(ecc_ptr++) = 0x00;
+			break;
+		default:
+			return -EINVAL;
 		}
+		/* update pointer to next sector */
+		ecc_calc += eccbytes;
 	}
-
 	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH || CONFIG_MTD_NAND_OMAP_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_elm_correct_data - corrects page data area in case error reported
  * @mtd:	MTD device structure
@@ -1773,7 +1712,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= nand_bch_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
 							(mtd->writesize /
@@ -1807,7 +1746,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap_elm_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
 		/* This ECC scheme requires ELM H/W block */
@@ -1839,7 +1778,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= nand_bch_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
 							(mtd->writesize /
@@ -1874,7 +1813,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap_elm_correct_data;
-		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
 		/* This ECC scheme requires ELM H/W block */
-- 
1.8.1



From pekon at ti.com  Mon Oct  7 06:55:02 2013
From: pekon at ti.com (Pekon Gupta)
Date: Mon, 7 Oct 2013 16:25:02 +0530
Subject: [PATCH v2 1/4] mtd: nand: omap: optimized chip->ecc.correct() for H/W
 ECC schemes
In-Reply-To: <1381143305-28617-1-git-send-email-pekon@ti.com>
References: <1381143305-28617-1-git-send-email-pekon@ti.com>
Message-ID: <1381143305-28617-2-git-send-email-pekon@ti.com>

chip->ecc.correct() is used for detecting and correcting bit-flips during read
operations. In omap2-nand driver this is done usingt following functions:

- omap_correct_data(): for H/W based HAM1_ECC schemes
	(Un-Touched in current patch)

- omap_elm_correct_data(): for H/W based BCHx_ECC scheme
	Current implementation of this function is not scalable for newer ECC
	schemes because:
	- It depends on a specific byte-position in OOB area (reserved as 0x00)
	  to differentiates between programmed-pages and erased-pages.
	  This reserved byte-position cannot be accomodated in all ECC schemes.
	- Current code is not scalable for future ECC schemes due to tweaks for
	  BCH4_ECC and BCH8_ECC at multiple places.
	- It checks for bit-flips in Erased-pages using check_erased_page().
	  This is over-work, as sanity of Erased-page can be verified by just
	  comparing them to a pre-defined ECC-syndrome for all_0xFF data.

	This patch optimizes omap_elm_correct_data() in following ways:
	(1) Removes dependency on specific reserved-byte (0x00) in OOB area,
	    instead Erased-page is identified by matching calc_ecc with a
	    pre-defined ECC syndrome of all(0xFF) data
	(2) merges common code for BCH4_ECC and BCH8_ECC for scalability.
	(3) handles incorrect elm_error_location beyond data+oob buffer.
	(4) removes check_erased_page(): Bit-flips in erased-page are handled
	    in same way as for programmed-page

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 270 +++++++++++++++--------------------------------
 1 file changed, 85 insertions(+), 185 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 0f2b0d1..c10a767 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -176,6 +176,7 @@ struct omap_nand_info {
 	int				gpmc_cs;
 	unsigned long			phys_base;
 	unsigned long			mem_size;
+	enum omap_ecc			ecc_opt;
 	struct completion		comp;
 	struct dma_chan			*dma;
 	int				gpmc_irq_fifo;
@@ -1307,219 +1308,118 @@ static int omap3_calculate_ecc_bch(struct mtd_info *mtd, const u_char *dat,
 }
 
 /**
- * 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 area with 0xFF
-	 */
-	if (flip_bits) {
-		memset(data, 0xFF, info->nand.ecc.size);
-		memset(oob, 0xFF, info->nand.ecc.bytes);
-	}
-
-	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.
- *
+ * @calc_ecc:	ecc calculated after reading Data and OOB regions from flash
+ * As calc_ecc is calculated over both main & oob, so calc_ecc would be
+ * non-zero only in following cases:
+ * - bit-flips in data or oob region
+ * - erase page, where no ECC is written in OOB area
+ *   However, erased_pages can be differentiated from corrupted pages
+ *   by comparing the calculated ECC with pre-defined syndrome ECC_of_ALL(0xFF)
+ *   Bit-flips in erased-pages would also be caught by comparing, calc_ecc
+ *   with ECC_of_ALL(0xFF)
  */
 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;
+	enum omap_ecc ecc_opt = info->ecc_opt;
+	struct nand_chip *chip = mtd->priv;
+	int eccsteps = chip->ecc.steps;
+	int eccsize  = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int i , j, stat = 0, ret = 0, flag_read_ecc;
 	struct elm_errorvec err_vec[ERROR_VECTOR_MAX];
-	u_char *ecc_vec = calc_ecc;
-	u_char *spare_ecc = read_ecc;
-	u_char *erased_ecc_vec;
-	enum bch_ecc type;
+	u_char *ecc;
 	bool is_error_reported = false;
+	u32 bit_pos, byte_pos, error_max, pos;
 
 	/* Initialize elm error vector to zero */
 	memset(err_vec, 0, sizeof(err_vec));
 
-	if (info->nand.ecc.strength == BCH8_MAX_ERROR) {
-		type = BCH8_ECC;
-		erased_ecc_vec = bch8_vector;
-	} else {
-		type = BCH4_ECC;
-		erased_ecc_vec = bch4_vector;
-	}
-
-	ecc_vector_size = info->nand.ecc.bytes;
-
-	/*
-	 * Remove extra byte padding for BCH8 RBL
-	 * compatibility and erased page handling
-	 */
-	eccsize = ecc_vector_size - 1;
-
 	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 */
+		flag_read_ecc = 0;
+		ecc = calc_ecc + (i * eccbytes);
+		/* check calc_ecc */
+		for (j = 0; j < eccbytes; j++) {
+			if (*(ecc + j) != 0x00) {
+				flag_read_ecc = 1;
 				break;
 			}
 		}
-
-		if (eccflag == 1) {
-			/*
-			 * Set threshold to minimum of 4, half of ecc.strength/2
-			 * to allow max bit flip in byte to 4
-			 */
-			unsigned int threshold = min_t(unsigned int, 4,
-					info->nand.ecc.strength / 2);
-
-			/*
-			 * Check data area is programmed by counting
-			 * number of 0's at fixed offset in spare area.
-			 * Checking count of 0's against threshold.
-			 * In case programmed page expects at least threshold
-			 * zeros in byte.
-			 * If zeros are less than threshold for programmed page/
-			 * zeros are more than threshold erased page, either
-			 * case page reported as uncorrectable.
-			 */
-			if (hweight8(~read_ecc[eccsize]) >= threshold) {
-				/*
-				 * 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;
-				}
+		/* check if its a erased-page */
+		if (flag_read_ecc) {
+			switch (ecc_opt) {
+			case OMAP_ECC_BCH8_CODE_HW:
+				if (memcmp(ecc, bch8_vector, eccbytes))
+					err_vec[i].error_reported = true;
+				break;
+			case OMAP_ECC_BCH4_CODE_HW:
+				if (memcmp(ecc, bch4_vector, eccbytes))
+					err_vec[i].error_reported = true;
+				break;
+			default:
+				pr_err("%s: invalid configuration",
+								 DRIVER_NAME);
+				return -EINVAL;
 			}
 		}
-
-		/* Update the ecc vector */
-		calc_ecc += ecc_vector_size;
-		read_ecc += ecc_vector_size;
+		/* page definitely has bit-flips */
+		if (err_vec[i].error_reported)
+			is_error_reported = true;
 	}
 
-	/* Check if any error reported */
 	if (!is_error_reported)
 		return 0;
+	/* detect bit-flips using ELM module */
+	elm_decode_bch_error_page(info->elm_dev, calc_ecc, err_vec);
 
-	/* Decode BCH error using ELM module */
-	elm_decode_bch_error_page(info->elm_dev, ecc_vec, err_vec);
-
+	/* correct bit-flip */
 	for (i = 0; i < eccsteps; i++) {
-		if (err_vec[i].error_reported) {
+		if (err_vec[i].error_uncorrectable) {
+			ret = -EBADMSG;
+		} else 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
+				switch (ecc_opt) {
+				case OMAP_ECC_BCH4_CODE_HW:
+					error_max = SECTOR_BYTES +
+							(eccbytes - 1);
 					/* Add 4 to take care 4 bit padding */
 					pos = err_vec[i].error_loc[j] +
-						BCH4_BIT_PAD;
-
-				/* Calculate bit position of error */
+							BCH4_BIT_PAD;
+					break;
+				case OMAP_ECC_BCH8_CODE_HW:
+					error_max = SECTOR_BYTES +
+							(eccbytes - 1);
+					pos = err_vec[i].error_loc[j];
+					break;
+				default:
+					return -EINVAL;
+				}
+				/* Calculate bit & byte bit-flip position */
 				bit_pos = pos % 8;
-
-				/* Calculate byte position of error */
-				byte_pos = (error_max - pos - 1) / 8;
-
-				if (pos < error_max) {
-					if (byte_pos < 512)
-						data[byte_pos] ^= 1 << bit_pos;
-					else
-						spare_ecc[byte_pos - 512] ^=
+				byte_pos = error_max - (pos / 8) - 1;
+				if (byte_pos < SECTOR_BYTES)
+					data[byte_pos] ^= 1 << bit_pos;
+				else if (byte_pos < error_max)
+					read_ecc[byte_pos - SECTOR_BYTES] ^=
 							1 << bit_pos;
-				}
-				/* else, not interested to correct ecc */
+				else
+					ret = -EBADMSG;
 			}
 		}
-
 		/* Update number of correctable errors */
 		stat += err_vec[i].error_count;
-
 		/* Update page data with sector size */
-		data += info->nand.ecc.size;
-		spare_ecc += ecc_vector_size;
+		data	 += eccsize;
+		read_ecc += eccbytes;
 	}
 
-	for (i = 0; i < eccsteps; i++)
-		/* Return error if uncorrectable error present */
-		if (err_vec[i].error_uncorrectable)
-			return -EINVAL;
-
-	return stat;
+	return (ret < 0) ? ret : stat;
 }
 
 /**
@@ -1677,7 +1577,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-
+	info->ecc_opt		= pdata->ecc_opt;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 	info->of_node		= pdata->of_node;
 
@@ -1872,7 +1772,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		info->nand.ecc.correct		= nand_bch_correct_data;
+		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1900,16 +1800,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	case OMAP_ECC_BCH4_CODE_HW:
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
-		info->nand.ecc.mode		= NAND_ECC_HW;
-		info->nand.ecc.size		= 512;
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
 		/* 14th bit is kept reserved for ROM-code compatibility */
-		info->nand.ecc.bytes		= 7 + 1;
-		info->nand.ecc.strength		= 4;
-		info->nand.ecc.hwctl		= omap3_enable_hwecc_bch;
-		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;
+		nand_chip->ecc.bytes		= 7 + 1;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
@@ -1938,7 +1838,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		info->nand.ecc.correct		= nand_bch_correct_data;
+		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
-- 
1.8.1



From pekon at ti.com  Mon Oct  7 06:55:04 2013
From: pekon at ti.com (Pekon Gupta)
Date: Mon, 7 Oct 2013 16:25:04 +0530
Subject: [PATCH v2 3/4] mtd: nand: omap: optimize chip->ecc.hwctl() for H/W
 ECC schemes
In-Reply-To: <1381143305-28617-1-git-send-email-pekon@ti.com>
References: <1381143305-28617-1-git-send-email-pekon@ti.com>
Message-ID: <1381143305-28617-4-git-send-email-pekon@ti.com>

chip->ecc.hwctl() is used for preparing the H/W controller before read/write
NAND accesses (like assigning data-buf, enabling ECC scheme configs, etc.)

Though all ECC schemes in OMAP NAND driver use GPMC controller for generating
ECC syndrome (for both Read/Write accesses). But but in current code
HAM1_ECC and BCHx_ECC schemes implement individual function to achieve this.
This patch merges the GPMC configuration code for all ECC schemes into
single omap_enable_hwecc(), thus adding scalability for future ECC schemes.

 omap_enable_hwecc() + omap3_enable_hwecc_bch() -> omap_enable_hwecc()

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 212 +++++++++++++++++------------------------------
 1 file changed, 74 insertions(+), 138 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index f9e5a4d..17cd5681 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -38,6 +38,10 @@
 #define	DRIVER_NAME	"omap2-nand"
 #define	OMAP_NAND_TIMEOUT_MS	5000
 
+#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 NAND_Ecc_P1e		(1 << 0)
 #define NAND_Ecc_P2e		(1 << 1)
 #define NAND_Ecc_P4e		(1 << 2)
@@ -106,13 +110,9 @@
 #define P4o_s(a)	(TF(a & NAND_Ecc_P4o)		<< 1)
 
 #define	PREFETCH_CONFIG1_CS_SHIFT	24
-#define	ECC_CONFIG_CS_SHIFT		1
 #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
 #define	ECC1				0x1
 #define	PREFETCH_FIFOTHRESHOLD_MAX	0x40
@@ -123,26 +123,9 @@
 
 #define OMAP24XX_DMA_GPMC		4
 
-#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 */
 
 #define BADBLOCK_MARKER_LENGTH		2
 
@@ -193,7 +176,6 @@ struct omap_nand_info {
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
-	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
 };
@@ -954,7 +936,7 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 	u32 val;
 
 	val = readl(info->reg.gpmc_ecc_config);
-	if (((val >> 1) & 0x07) != info->gpmc_cs) {
+	if (((val >> 1) & 0x7) != info->gpmc_cs) {
 		pr_err("%s: invalid ECC configuration for chip-select=%d",
 				DRIVER_NAME, info->gpmc_cs);
 		return -EINVAL;
@@ -970,47 +952,6 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
 }
 
 /**
- * omap_enable_hwecc - This function enables the hardware ecc functionality
- * @mtd: MTD device structure
- * @mode: Read/Write mode
- */
-static void omap_enable_hwecc(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;
-	unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
-	u32 val;
-
-	/* clear ecc and enable bits */
-	val = ECCCLEAR | ECC1;
-	writel(val, info->reg.gpmc_ecc_control);
-
-	/* program ecc and result sizes */
-	val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) |
-			 ECC1RESULTSIZE);
-	writel(val, info->reg.gpmc_ecc_size_config);
-
-	switch (mode) {
-	case NAND_ECC_READ:
-	case NAND_ECC_WRITE:
-		writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
-		break;
-	case NAND_ECC_READSYN:
-		writel(ECCCLEAR, info->reg.gpmc_ecc_control);
-		break;
-	default:
-		dev_info(&info->pdev->dev,
-			"error: unrecognized Mode[%d]!\n", mode);
-		break;
-	}
-
-	/* (ECC 16 or 8 bit col) | ( CS  )  | ECC Enable */
-	val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1);
-	writel(val, info->reg.gpmc_ecc_config);
-}
-
-/**
  * omap_wait - wait until the command is done
  * @mtd: MTD device structure
  * @chip: NAND Chip structure
@@ -1066,88 +1007,85 @@ static int omap_dev_ready(struct mtd_info *mtd)
 	}
 }
 
-#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
- * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
+ * omap_enable_hwecc - Configure OMAP GPMC to perform ECC calculation
  * @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)
+ * Configurations for eccsize0, eccsize1, and bch_wrapmode are based on
+ * GPMC function spec:
+ * Section 4.6.3.2.3: Supported NAND page mappings and ECC schemes
  */
-static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
+static void omap_enable_hwecc(struct mtd_info *mtd, int mode)
 {
-	int nerrors;
-	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, wr_mode;
-	unsigned int ecc_size1, ecc_size0;
-
-	/* Using wrapping mode 6 for writing */
-	wr_mode = BCH_WRAPMODE_6;
-
-	/*
-	 * ECC engine enabled for valid ecc_size0 nibbles
-	 * and disabled for ecc_size1 nibbles.
-	 */
-	ecc_size0 = BCH_ECC_SIZE0;
-	ecc_size1 = BCH_ECC_SIZE1;
-
-	/* Perform ecc calculation on 512-byte sector */
-	nsectors = 1;
-
-	/* Update number of error correction */
-	nerrors = info->nand.ecc.strength;
-
-	/* Multi sector reading/writing for NAND flash with page size < 4096 */
-	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
-			 * and 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;
+	unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
+	unsigned int nsectors = (mtd->writesize / SECTOR_BYTES);
+	unsigned int ecc_algo = 0;
+	unsigned int bch_type = 0;
+	unsigned int eccsize1 = 0x00, eccsize0 = 0x00, bch_wrapmode = 0x00;
+	u32 ecc_size_config_val = 0;
+	u32 ecc_config_val = 0;
+
+	switch (info->ecc_opt) {
+	case OMAP_ECC_HAM1_CODE_HW:
+		ecc_algo = 0x0;
+		bch_wrapmode = 0x00;
+		eccsize0 = (chip->ecc.size >> 1) - 1;
+		eccsize1 = 0;
+		nsectors = 0;
+		break;
+	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+	case OMAP_ECC_BCH4_CODE_HW:
+		ecc_algo = 0x1;
+		bch_type = 0x0;
+		if (mode == GPMC_ECC_READ) {
+			bch_wrapmode = 0x01;
+			eccsize0 = 13; /* ECC bits in nibbles per sector */
+			eccsize1 = 3;  /* non-ECC bits in nibbles per sector */
+		} else if (mode == GPMC_ECC_WRITE) {
+			eccsize0 = 0;  /* extra bits in nibbles per sector */
+			eccsize1 = 32; /* OOB bits in nibbles per sector */
+			bch_wrapmode = 0x06;
 		}
-
-		/* Perform ecc calculation for one page (< 4096) */
-		nsectors = info->nand.ecc.steps;
+		break;
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+	case OMAP_ECC_BCH8_CODE_HW:
+		ecc_algo = 0x1;
+		bch_type = 0x1;
+		if (mode == GPMC_ECC_READ) {
+			bch_wrapmode = 0x01;
+			eccsize0 = 26; /* ECC bits in nibbles per sector */
+			eccsize1 = 2;  /* non-ECC bits in nibbles per sector */
+		} else if (mode == GPMC_ECC_WRITE) {
+			bch_wrapmode = 0x01;
+			eccsize0 = 0;  /* extra bits in nibbles per sector */
+			eccsize1 = 28; /* OOB bits in nibbles per sector */
+		}
+		break;
+	default:
+		pr_err("selected ECC scheme not supported or not enabled\n");
 	}
-
-	writel(ECC1, info->reg.gpmc_ecc_control);
-
+	/* clear previous ecc result and enable engine */
+	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 	/* Configure ecc size for BCH */
-	val = (ecc_size1 << ECCSIZE1_SHIFT) | (ecc_size0 << ECCSIZE0_SHIFT);
-	writel(val, info->reg.gpmc_ecc_size_config);
-
-	dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;
-
-	/* BCH configuration */
-	val = ((1                        << 16) | /* enable BCH */
-	       (((nerrors == 8) ? 1 : 0) << 12) | /* 8 or 4 bits */
-	       (wr_mode                  <<  8) | /* wrap mode */
-	       (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 */
+	ecc_size_config_val = (eccsize1 << 22) | (eccsize0 << 12);
+	writel(ecc_size_config_val, info->reg.gpmc_ecc_size_config);
+	/* Configure device details for BCH engine */
+	ecc_config_val = ((ecc_algo << 16)	| /* HAM1 | BCHx */
+			(bch_type << 12)	| /* BCH4/BCH8/BCH16 */
+			(bch_wrapmode << 8)	| /* wrap mode */
+			(dev_width << 7)	| /* bus width */
+			(((nsectors-1) & 0x7) << 4) | /* number of sectors */
+			(info->gpmc_cs <<  1)	| /* ECC CS */
+			(0x1));			  /* enable ECC */
+	writel(ecc_config_val, info->reg.gpmc_ecc_config);
+	/* Clear ecc and re-enable */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
 
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
  * omap_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1456,7 +1394,6 @@ static int is_elm_present(struct omap_nand_info *info,
 			struct device_node *elm_node, enum bch_ecc bch_type)
 {
 	struct platform_device *pdev;
-	info->is_elm_used = false;
 	/* check whether elm-id is passed via DT */
 	if (!elm_node) {
 		pr_err("nand: error: ELM DT node not found\n");
@@ -1472,7 +1409,6 @@ static int is_elm_present(struct omap_nand_info *info,
 	info->elm_dev = &pdev->dev;
 	if (elm_config(info->elm_dev, bch_type))
 		return -ENODEV;
-	info->is_elm_used = true;
 	return 0;
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
@@ -1710,7 +1646,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.size		= 512;
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
-		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.hwctl		= omap_enable_hwecc;
 		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		/* define custom ECC layout */
@@ -1744,7 +1680,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		/* 14th bit is kept reserved for ROM-code compatibility */
 		nand_chip->ecc.bytes		= 7 + 1;
 		nand_chip->ecc.strength		= 4;
-		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.hwctl		= omap_enable_hwecc;
 		nand_chip->ecc.correct		= omap_elm_correct_data;
 		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
@@ -1776,7 +1712,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.size		= 512;
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
-		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.hwctl		= omap_enable_hwecc;
 		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		/* define custom ECC layout */
@@ -1811,7 +1747,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		/* 14th bit is kept reserved for ROM-code compatibility */
 		nand_chip->ecc.bytes		= 13 + 1;
 		nand_chip->ecc.strength		= 8;
-		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.hwctl		= omap_enable_hwecc;
 		nand_chip->ecc.correct		= omap_elm_correct_data;
 		nand_chip->ecc.calculate	= omap_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
-- 
1.8.1



From pekon at ti.com  Mon Oct  7 06:55:05 2013
From: pekon at ti.com (Pekon Gupta)
Date: Mon, 7 Oct 2013 16:25:05 +0530
Subject: [PATCH v2 4/4] mtd: devices: elm: add checks ELM H/W constrains,
 driver code cleanup
In-Reply-To: <1381143305-28617-1-git-send-email-pekon@ti.com>
References: <1381143305-28617-1-git-send-email-pekon@ti.com>
Message-ID: <1381143305-28617-5-git-send-email-pekon@ti.com>

ELM H/W engine is used by BCHx_ECC schemes for detecting and locating bit-flips.
However, ELM H/W engine has some constrains like:
- ELM can decode errors in chunks of 512 data bytes only
- ELM can operate max upto 8 such buffers in parallel

This patch
- add checks for above constrains
- fixes ELM register configs based on number of info->eccsteps
- cleans-up elm_load_syndrome()

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/devices/elm.c         | 122 ++++++++++++++++++++++----------------
 drivers/mtd/nand/omap2.c          |   2 +-
 include/linux/platform_data/elm.h |   6 +-
 3 files changed, 77 insertions(+), 53 deletions(-)

diff --git a/drivers/mtd/devices/elm.c b/drivers/mtd/devices/elm.c
index d1dd6a3..2167384 100644
--- a/drivers/mtd/devices/elm.c
+++ b/drivers/mtd/devices/elm.c
@@ -22,8 +22,11 @@
 #include <linux/of.h>
 #include <linux/sched.h>
 #include <linux/pm_runtime.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
 #include <linux/platform_data/elm.h>
 
+#define	DRIVER_NAME			"omap-elm"
 #define ELM_SYSCONFIG			0x010
 #define ELM_IRQSTATUS			0x018
 #define ELM_IRQENABLE			0x01c
@@ -82,8 +85,10 @@ struct elm_info {
 	void __iomem *elm_base;
 	struct completion elm_completion;
 	struct list_head list;
+	struct mtd_info *mtd;
 	enum bch_ecc bch_type;
 	struct elm_registers elm_regs;
+	int eccsteps;
 };
 
 static LIST_HEAD(elm_devices);
@@ -103,19 +108,42 @@ static u32 elm_read_reg(struct elm_info *info, int offset)
  * @dev:	ELM device
  * @bch_type:	Type of BCH ecc
  */
-int elm_config(struct device *dev, enum bch_ecc bch_type)
+int elm_config(struct device *dev, struct mtd_info *mtd,
+		enum bch_ecc bch_type)
 {
 	u32 reg_val;
-	struct elm_info *info = dev_get_drvdata(dev);
-
+	struct elm_info	 *info;
+	struct nand_chip *chip;
+	if (!dev) {
+		pr_err("%s: ELM device not found\n", DRIVER_NAME);
+		return -ENODEV;
+	}
+	info = dev_get_drvdata(dev);
 	if (!info) {
-		dev_err(dev, "Unable to configure elm - device not probed?\n");
+		pr_err("%s: ELM device data not found\n", DRIVER_NAME);
 		return -ENODEV;
 	}
-
+	if (!mtd) {
+		pr_err("%s: MTD device not found\n", DRIVER_NAME);
+		return -ENODEV;
+	}
+	chip = mtd->priv;
+	/* ELM supports error correction in chunks of 512bytes of data only
+	 * where each 512bytes of data has its own ECC syndrome */
+	if (chip->ecc.size != 512) {
+		pr_err("%s: invalid ecc_size configuration", DRIVER_NAME);
+		return -EINVAL;
+	}
+	if (mtd->writesize > 4096) {
+		pr_err("%s: page-size > 4096 is not supported", DRIVER_NAME);
+		return -EINVAL;
+	}
+	/* ELM eccsteps required to decode complete NAND page */
+	info->mtd	= mtd;
+	info->bch_type	= bch_type;
+	info->eccsteps = mtd->writesize / chip->ecc.size;
 	reg_val = (bch_type & ECC_BCH_LEVEL_MASK) | (ELM_ECC_SIZE << 16);
 	elm_write_reg(info, ELM_LOCATION_CONFIG, reg_val);
-	info->bch_type = bch_type;
 
 	return 0;
 }
@@ -152,55 +180,51 @@ static void elm_configure_page_mode(struct elm_info *info, int index,
  * 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)
+		struct elm_errorvec *err_vec, u8 *ecc_calc)
 {
+	struct nand_chip *chip	= info->mtd->priv;
+	unsigned int eccbytes	= chip->ecc.bytes;
+	u8 *ecc = ecc_calc;
 	int i, offset;
 	u32 val;
 
-	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
-
+	for (i = 0; i < info->eccsteps; 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);
-
-				/* syndrome fragment 1 = ecc[0-20b] bits */
-				offset += 4;
-				val = cpu_to_be32(*(u32 *) &ecc[0]) >> 12;
-				elm_write_reg(info, offset, val);
+			offset = SYNDROME_FRAGMENT_REG_SIZE * i;
+			ecc = ecc_calc + (i * eccbytes);
+			switch (info->bch_type) {
+			case BCH4_ECC:
+				val =	((*(ecc + 6) >>  4) & 0x0F) |
+					*(ecc +  5) <<  4 | *(ecc +  4) << 12 |
+					*(ecc +  3) << 20 | *(ecc +  2) << 28;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_0 +
+						 offset), cpu_to_le32(val));
+				val =	((*(ecc + 2) >>  4) & 0x0F) |
+					*(ecc +  1) <<  4 | *(ecc +  0) << 12;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_1 +
+						 offset), cpu_to_le32(val));
+				break;
+			case BCH8_ECC:
+				val =	*(ecc + 12) << 0  | *(ecc + 11) <<  8 |
+					*(ecc + 10) << 16 | *(ecc +  9) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_0 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc +  8) <<  0 | *(ecc +  7) <<  8 |
+					*(ecc +  6) << 16 | *(ecc +  5) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_1 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc +  4) <<  0 | *(ecc +  3) <<  8 |
+					*(ecc +  2) << 16 | *(ecc +  1) << 24;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_2 +
+						 offset), cpu_to_le32(val));
+				val =	*(ecc +  0) <<  0 & 0x000000FF;
+				elm_write_reg(info, (ELM_SYNDROME_FRAGMENT_3 +
+						 offset), cpu_to_le32(val));
+				break;
 			}
 		}
-
-		/* Update ecc pointer with ecc byte size */
-		ecc += info->bch_type ? BCH8_SIZE : BCH4_SIZE;
 	}
 }
 
@@ -223,7 +247,7 @@ static void elm_start_processing(struct elm_info *info,
 	 * Set syndrome vector valid, so that ELM module
 	 * will process it for vectors error is reported
 	 */
-	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+	for (i = 0; i < info->eccsteps; i++) {
 		if (err_vec[i].error_reported) {
 			offset = ELM_SYNDROME_FRAGMENT_6 +
 				SYNDROME_FRAGMENT_REG_SIZE * i;
@@ -252,7 +276,7 @@ static void elm_error_correction(struct elm_info *info,
 	int offset;
 	u32 reg_val;
 
-	for (i = 0; i < ERROR_VECTOR_MAX; i++) {
+	for (i = 0; i < info->eccsteps; i++) {
 
 		/* Check error reported */
 		if (err_vec[i].error_reported) {
@@ -263,14 +287,12 @@ static void elm_error_correction(struct elm_info *info,
 			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;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 17cd5681..e0b1f98 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1407,7 +1407,7 @@ static int is_elm_present(struct omap_nand_info *info,
 	}
 	/* ELM module available, now configure it */
 	info->elm_dev = &pdev->dev;
-	if (elm_config(info->elm_dev, bch_type))
+	if (elm_config(info->elm_dev, &info->mtd, bch_type))
 		return -ENODEV;
 	return 0;
 }
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h
index bf0a83b..d16465b 100644
--- a/include/linux/platform_data/elm.h
+++ b/include/linux/platform_data/elm.h
@@ -25,6 +25,7 @@ enum bch_ecc {
 
 /* ELM support 8 error syndrome process */
 #define ERROR_VECTOR_MAX		8
+#define ELM_MAX_DETECTABLE_ERRORS	16
 
 #define BCH8_ECC_OOB_BYTES		13
 #define BCH4_ECC_OOB_BYTES		7
@@ -45,10 +46,11 @@ struct elm_errorvec {
 	bool error_reported;
 	bool error_uncorrectable;
 	int error_count;
-	int error_loc[ERROR_VECTOR_MAX];
+	int error_loc[ELM_MAX_DETECTABLE_ERRORS];
 };
 
 void elm_decode_bch_error_page(struct device *dev, u8 *ecc_calc,
 		struct elm_errorvec *err_vec);
-int elm_config(struct device *dev, enum bch_ecc bch_type);
+int elm_config(struct device *dev, struct mtd_info *mtd,
+		enum bch_ecc bch_type);
 #endif /* __ELM_H */
-- 
1.8.1



From sourav.poddar at ti.com  Mon Oct  7 07:26:03 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Mon, 7 Oct 2013 16:56:03 +0530
Subject: Memory mapped support for SPI flash ?
Message-ID: <52529A4B.6040501@ti.com>

Hi,

I wanted to know whether there is any framework or support available
in mtd which helps in doing a memory mapped read for a serial NOR flash 
driver.

Requirement is something like this..

My controller supports memory mapped read, but needs to switch to
memory mapped port to read from it and once the
read is done switch back again to normal configuration mode.

So, my idea is that spi controller need to be communicated from  the mtd 
layer
that the current read is memory mapped read, so the controller does
whatever settings need to be done and then does the memory mapped read and
switch back to configuration mode.

I see some drivers under drivers/mtd/maps/* , point and unpoint 
functions, but are they
applicable for serial NOR flashes? Or there is any other stuff available 
which I can use
for my usecase?

I was thing of using it in a way that dual/quad support is used. I mean 
to add "memory map"
as a mode and pass it as a transfer parameter(from the mtd layer) to 
indicate that the current transfer
is a memory map read and then do a memcopy in the low level driver function.

Thanks in advance,
Sourav



From mark.rutland at arm.com  Mon Oct  7 07:27:28 2013
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 7 Oct 2013 12:27:28 +0100
Subject: [PATCH v7 1/6] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <1380916188-24206-2-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-2-git-send-email-pekon@ti.com>
Message-ID: <20131007112728.GA15365@e106331-lin.cambridge.arm.com>

On Fri, Oct 04, 2013 at 08:49:43PM +0100, Pekon Gupta wrote:
> OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
> ecc-scheme, like:
> - OMAP_ECC_HAMMING_CODE_DEFAULT
> 	1-bit hamming ecc code using software library
> - OMAP_ECC_HAMMING_CODE_HW
> 	1-bit hamming ecc-code using GPMC h/w engine
> - OMAP_ECC_HAMMING_CODE_HW_ROMCODE
> 	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
> 	to ROM code.
> 
> This patch combines above multiple ecc-schemes into single implementation:
> - OMAP_ECC_HAM1_CODE_HW
> 	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
> 	ecc-layout.

If I have my NAND formatted with one of the existing ECC schemes (e.g.
OMAP_ECC_HAMMING_CODE_DEFAULT) will it work with the new
OMAP_ECC_HAM1_CODE_HW scheme?

Are they all compatible?

> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
>  arch/arm/mach-omap2/board-flash.c                   | 2 +-
>  arch/arm/mach-omap2/gpmc.c                          | 4 +---
>  drivers/mtd/nand/omap2.c                            | 9 +++------
>  include/linux/platform_data/mtd-nand-omap2.h        | 6 +-----
>  5 files changed, 10 insertions(+), 19 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> index df338cb..25ee232 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> @@ -22,10 +22,10 @@ Optional properties:
>  				width of 8 is assumed.
>  
>   - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
> -
> -		"sw"		Software method (default)
> -		"hw"		Hardware method
> -		"hw-romcode"	gpmc hamming mode method & romcode layout
> +		"sw"		<deprecated> use "ham1" instead
> +		"hw"		<deprecated> use "ham1" instead
> +		"hw-romcode"	<deprecated> use "ham1" instead
> +		"ham1"		1-bit Hamming ecc code
>  		"bch4"		4-bit BCH ecc code
>  		"bch8"		8-bit BCH ecc code
>  
> diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
> index fc20a61..ac82512 100644
> --- a/arch/arm/mach-omap2/board-flash.c
> +++ b/arch/arm/mach-omap2/board-flash.c
> @@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
>  	board_nand_data.nr_parts	= nr_parts;
>  	board_nand_data.devsize		= nand_type;
>  
> -	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
> +	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
>  	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/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 9f4795a..1c45b72 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1342,9 +1342,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  #ifdef CONFIG_MTD_NAND
>  
>  static const char * const nand_ecc_opts[] = {
> -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
> +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
>  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
>  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",

Won't this break existing dts which have "sw", "hw", or "hw-romcode"?

Someone may try to use a new kernel with an old dt, and we marked them
as deprecated, not removed.

Thanks,
Mark.


From mark.rutland at arm.com  Mon Oct  7 07:35:48 2013
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 7 Oct 2013 12:35:48 +0100
Subject: [PATCH v7 2/6] ARM: OMAP2+: cleaned-up DT support of various
 ECC schemes
In-Reply-To: <1380916188-24206-3-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-3-git-send-email-pekon@ti.com>
Message-ID: <20131007113547.GB15365@e106331-lin.cambridge.arm.com>

On Fri, Oct 04, 2013 at 08:49:44PM +0100, Pekon Gupta wrote:
> OMAP NAND driver support multiple ECC scheme, which can used in following
> different flavours, depending on in-build Hardware engines supported by SoC.
> 
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
> |(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> |(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
> | ti,elm-id in DT)                      |               |               |
> +---------------------------------------+---------------+---------------+
> To optimize footprint of omap2-nand driver, selection of some ECC schemes
> also require enabling following Kconfigs, in addition to setting appropriate
> DT bindings
> - Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
> - Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine
> 
> DT binding updates in this patch are:
> - ti,elm-id: replaces elm_id
> - ti,nand-ecc-opts: supported values ham1, bch4, and bch8
> 	selection of h/w or s/w implementation depends on ti,elm-id
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
>  arch/arm/mach-omap2/gpmc.c                         | 47 ++++++++++++++++------
>  include/linux/platform_data/mtd-nand-omap2.h       | 14 +++++--
>  3 files changed, 52 insertions(+), 17 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> index 25ee232..7785666 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> @@ -36,8 +36,12 @@ Optional properties:
>  		"prefetch-dma"		Prefetch enabled sDMA mode
>  		"prefetch-irq"		Prefetch enabled irq mode
>  
> - - elm_id:	Specifies elm device node. This is required to support BCH
> - 		error correction using ELM module.
> + - elm_id:	<deprecated> use "ti,elm-id" instead
> + - ti,elm-id:	Specifies pHandle of the ELM devicetree node.

s/pHandle/phandle/

> +		ELM is an on-chip hardware engine on TI SoC which is used for
> +		locating ECC errors for BCHx algorithms. SoC devices which have
> +		ELM hardware engines should specify this device node in .dtsi
> +		Using ELM for ECC error correction frees some CPU cycles.
>  
>  For inline partiton table parsing (optional):
>  
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 1c45b72..5a607fa 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1341,12 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  
>  #ifdef CONFIG_MTD_NAND
>  
> -static const char * const nand_ecc_opts[] = {
> -	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> -	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> -	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> -};
> -
>  static const char * const nand_xfer_types[] = {
>  	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
>  	[NAND_OMAP_POLLED]			= "polled",
> @@ -1361,6 +1355,8 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
>  	const char *s;
>  	struct gpmc_timings gpmc_t;
>  	struct omap_nand_platform_data *gpmc_nand_data;
> +	const __be32 *phandle;

I don't think you need this. With of_parse_phandle you should never need
to see the raw phandle value.

> +	int lenp;
>  
>  	if (of_property_read_u32(child, "reg", &val) < 0) {
>  		dev_err(&pdev->dev, "%s has no 'reg' property\n",
> @@ -1376,12 +1372,39 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
>  	gpmc_nand_data->cs = val;
>  	gpmc_nand_data->of_node = child;
>  
> -	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
> -		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
> -			if (!strcasecmp(s, nand_ecc_opts[val])) {
> -				gpmc_nand_data->ecc_opt = val;
> -				break;
> -			}
> +	/* Detect availability of ELM module */
> +	phandle = of_get_property(child, "ti,elm-id", &lenp);
> +	if ((phandle == NULL) || (lenp != sizeof(void *))) {
> +		pr_warn("%s: ti,elm-id property not found\n", __func__);
> +		gpmc_nand_data->elm_of_node = NULL;
> +	} else {
> +		gpmc_nand_data->elm_of_node =
> +				of_find_node_by_phandle(be32_to_cpup(phandle));
> +	}

Use of_parse_handle rather than open-coding it:

	gpmc_nand_data->elm_of_node = 
		of_parse_phandle(child, "ti,elm-id", 0);

Was "elm_id" ever handled previously? I don't see any code handling it
being remove or modified.

Thanks,
Mark.


From mark.rutland at arm.com  Mon Oct  7 07:40:30 2013
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 7 Oct 2013 12:40:30 +0100
Subject: [PATCH v7 5/6] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1380916188-24206-6-git-send-email-pekon@ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-6-git-send-email-pekon@ti.com>
Message-ID: <20131007114029.GC15365@e106331-lin.cambridge.arm.com>

On Fri, Oct 04, 2013 at 08:49:47PM +0100, Pekon Gupta wrote:
> DT property values for OMAP based gpmc-nand have been updated
> to match changes in commit:
> 	6faf096 ARM: OMAP2+: cleaned-up DT support of various ECC schemes
> Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt

Doesn't this mean these dts were broken between the changes to the
driver and the changes to the dts?

I think the existing properties need to continue to be supoprted for
backwards compatibility. The dts can be fixed up to have the preferred
binding style, but they shouldn't _have_ to be modified to continue to
function...

Thanks,
Mark.

> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  arch/arm/boot/dts/am335x-evm.dts   | 3 +--
>  arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
> index e8ec875..1aee6ac 100644
> --- a/arch/arm/boot/dts/am335x-evm.dts
> +++ b/arch/arm/boot/dts/am335x-evm.dts
> @@ -269,7 +269,6 @@
>  				reg = <0 0 0>; /* CS0, offset 0 */
>  				nand-bus-width = <8>;
>  				ti,nand-ecc-opt = "bch8";
> -				gpmc,device-nand = "true";
>  				gpmc,device-width = <1>;
>  				gpmc,sync-clk-ps = <0>;
>  				gpmc,cs-on-ns = <0>;
> @@ -296,7 +295,7 @@
>  
>  				#address-cells = <1>;
>  				#size-cells = <1>;
> -				elm_id = <&elm>;
> +				ti,elm-id = <&elm>;
>  
>  				/* MTD partition table */
>  				partition at 0 {
> diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
> index e2249bc..501f863 100644
> --- a/arch/arm/boot/dts/omap3430-sdp.dts
> +++ b/arch/arm/boot/dts/omap3430-sdp.dts
> @@ -105,7 +105,7 @@
>  		reg = <1 0 0x08000000>;
>  		nand-bus-width = <8>;
>  
> -		ti,nand-ecc-opt = "sw";
> +		ti,nand-ecc-opt = "ham1";
>  		gpmc,cs-on-ns = <0>;
>  		gpmc,cs-rd-off-ns = <36>;
>  		gpmc,cs-wr-off-ns = <36>;
> -- 
> 1.8.1
> 
> 


From pekon at ti.com  Mon Oct  7 07:42:19 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Mon, 7 Oct 2013 11:42:19 +0000
Subject: [PATCH v7 1/6] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <20131007112728.GA15365@e106331-lin.cambridge.arm.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-2-git-send-email-pekon@ti.com>
 <20131007112728.GA15365@e106331-lin.cambridge.arm.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA1F3DC@DBDE04.ent.ti.com>

Hi,

> From: Mark Rutland [mailto:mark.rutland at arm.com]
> > On Fri, Oct 04, 2013 at 08:49:43PM +0100, Pekon Gupta wrote:
> > OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
> > ecc-scheme, like:
> > - OMAP_ECC_HAMMING_CODE_DEFAULT
> > 	1-bit hamming ecc code using software library
> > - OMAP_ECC_HAMMING_CODE_HW
> > 	1-bit hamming ecc-code using GPMC h/w engine
> > - OMAP_ECC_HAMMING_CODE_HW_ROMCODE
> > 	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout
> compatible
> > 	to ROM code.
> >
> > This patch combines above multiple ecc-schemes into single
> implementation:
> > - OMAP_ECC_HAM1_CODE_HW
> > 	1-bit hamming ecc-code using GPMC h/w engine with ROM-code
> compatible
> > 	ecc-layout.
> 
> If I have my NAND formatted with one of the existing ECC schemes (e.g.
> OMAP_ECC_HAMMING_CODE_DEFAULT) will it work with the new
> OMAP_ECC_HAM1_CODE_HW scheme?
> 
> Are they all compatible?
> 
Yes, they all are 1-bit hamming code, the only difference between 
xx_Default and xx_HW was who was doing the ECC calculation.
For xx_DEFAULT: ECC calculation was done on CPU via s/w library
For xx_HW: ECC calculation was done by in-build h/w engine.
So, all HAMMING_xx can be replaced by HAM1_HW.

[snip]

> > @@ -1342,9 +1342,7 @@ static void __maybe_unused
> gpmc_read_timings_dt(struct device_node *np,
> >  #ifdef CONFIG_MTD_NAND
> >
> >  static const char * const nand_ecc_opts[] = {
> > -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> > -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> > -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-
> romcode",
> > +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> >  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> >  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> 
> Won't this break existing dts which have "sw", "hw", or "hw-romcode"?
> 
> Someone may try to use a new kernel with an old dt, and we marked them
> as deprecated, not removed.
> 
HAMMING_xx ECC scheme was used only on legacy platforms, when
BCH8 was not available, I have not seen anyone using this scheme
*from mainline kernel* from quite a long time. So, it's safe to remove them.

This is what was concluded as per below email.
http://lists.infradead.org/pipermail/linux-mtd/2013-September/048876.html

with regards, pekon


From sourav.poddar at ti.com  Mon Oct  7 08:11:17 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Mon, 7 Oct 2013 17:41:17 +0530
Subject: [PATCHv2] drivers: mtd: devices: Add quad read support.
In-Reply-To: <1380191565-28640-1-git-send-email-sourav.poddar@ti.com>
References: <1380191565-28640-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <5252A4E5.3000202@ti.com>

Hi Brian,
On Thursday 26 September 2013 04:02 PM, Sourav Poddar wrote:
> Some flash also support quad read mode.
> Adding support for adding quad mode in m25p80.
>
> Signed-off-by: Sourav Poddar<sourav.poddar at ti.com>
> ---
> v1->v2:
> - Make the code more modular
> - put proper error checks
>   drivers/mtd/devices/m25p80.c |  155 +++++++++++++++++++++++++++++++++++++++---
>   1 files changed, 144 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 26b14f9..3c8a794 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -41,6 +41,7 @@
>   #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
>   #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
>   #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
> +#define	OPCODE_QUAD_READ	0x6b	/* QUAD READ */
>   #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
>   #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
>   #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
> @@ -48,10 +49,12 @@
>   #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
>   #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
>   #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
> +#define	OPCODE_RDCR		0x35	/* Read configuration register */
>
>   /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>   #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
>   #define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high frequency) */
> +#define	OPCODE_QUAD_READ_4B     0x6c    /* Read data bytes */
>   #define	OPCODE_PP_4B		0x12	/* Page program (up to 256 bytes) */
>   #define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
>
> @@ -76,6 +79,9 @@
>   #define	SR_BP2			0x10	/* Block protect 2 */
>   #define	SR_SRWD			0x80	/* SR write protect */
>
> +/* Configuration Register bits. */
> +#define	QUAD_CR_EN		0x2	/* Quad I/O */
> +
>   /* Define max times to check status register before we give up. */
>   #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
>   #define	MAX_CMD_SIZE		5
> @@ -95,6 +101,7 @@ struct m25p {
>   	u8			program_opcode;
>   	u8			*command;
>   	bool			fast_read;
> +	bool			quad_read;
>   };
>
>   static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
> @@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)
>   	return spi_write_then_read(flash->spi,&code, 1, NULL, 0);
>   }
>
> +/* Read the configuration register, returning its value in the location
> + * Return the configuration register value.
> + * Returns negative if error occurred.
> +*/
> +static int read_cr(struct m25p *flash)
> +{
> +	u8 code = OPCODE_RDCR;
> +	int ret;
> +	u8 val;
> +
> +	ret = spi_write_then_read(flash->spi,&code, 1,&val, 1);
> +	if (ret<  0) {
> +		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
> +		return ret;
> +	}
> +
> +	return val;
> +}
> +
>   /*
>    * Enable/disable 4-byte addressing mode.
>    */
> @@ -336,6 +362,97 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
>   	return 0;
>   }
>
> +/* Write status register and configuration register with 2 bytes
> +* The first byte will be written to the status register, while the second byte
> +* will be written to the configuration register.
> +* Returns negative if error occurred.
> +*/
> +static int write_sr_cr(struct m25p *flash, u16 val)
> +{
> +	flash->command[0] = OPCODE_WRSR;
> +	flash->command[1] = val&  0xff;
> +	flash->command[2] = (val>>  8);
> +
> +	return spi_write(flash->spi, flash->command, 3);
> +}
> +
> +static int quad_enable(struct m25p *flash)
> +{
> +	int ret;
> +	int quad_en = QUAD_CR_EN<<  8;
> +
> +	write_enable(flash);
> +
> +	ret = write_sr_cr(flash, quad_en);
> +	if (ret<  0) {
> +		dev_err(&flash->spi->dev,
> +			"error while writing configuration register");
> +		return -EINVAL;
> +	}
> +
> +	/* read back and check it */
> +	ret = read_cr(flash);
> +	if (!(ret>  0&&  (ret&  QUAD_CR_EN))) {
> +		dev_err(&flash->spi->dev,
> +			"Quad bit not set");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
> +	size_t *retlen, u_char *buf)
> +{
> +	struct m25p *flash = mtd_to_m25p(mtd);
> +	struct spi_transfer t[2];
> +	struct spi_message m;
> +	uint8_t opcode;
> +
> +	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
> +			__func__, (u32)from, len);
> +
> +	spi_message_init(&m);
> +	memset(t, 0, (sizeof(t)));
> +
> +	t[0].tx_buf = flash->command;
> +	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
> +	spi_message_add_tail(&t[0],&m);
> +
> +	t[1].rx_buf = buf;
> +	t[1].len = len;
> +	t[1].rx_nbits = SPI_NBITS_QUAD;
> +	spi_message_add_tail(&t[1],&m);
> +
> +	mutex_lock(&flash->lock);
> +
> +	/* Wait till previous write/erase is done. */
> +	if (wait_till_ready(flash)) {
> +		/* REVISIT status return?? */
> +		mutex_unlock(&flash->lock);
> +		return 1;
> +	}
> +
> +	/* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
> +	 * clocks; and at this writing, every chip this driver handles
> +	 * supports that opcode.
> +	*/
> +
> +	/* Set up the write data buffer. */
> +	opcode = flash->read_opcode;
> +	flash->command[0] = opcode;
> +	m25p_addr2cmd(flash, from, flash->command);
> +
> +	spi_sync(flash->spi,&m);
> +
> +	*retlen = m.actual_length - m25p_cmdsz(flash) -
> +			(flash->quad_read ? 1 : 0);
> +
> +	mutex_unlock(&flash->lock);
> +
> +	return 0;
> +}
> +
>   /*
>    * Read an address range from the flash chip.  The address range
>    * may be any size provided it is within the physical boundaries.
> @@ -928,6 +1045,7 @@ static int m25p_probe(struct spi_device *spi)
>   	unsigned			i;
>   	struct mtd_part_parser_data	ppdata;
>   	struct device_node __maybe_unused *np = spi->dev.of_node;
> +	int ret;
>
>   #ifdef CONFIG_MTD_OF_PARTS
>   	if (!of_device_is_available(np))
> @@ -979,15 +1097,9 @@ static int m25p_probe(struct spi_device *spi)
>   		}
>   	}
>
> -	flash = kzalloc(sizeof *flash, GFP_KERNEL);
> +	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
>   	if (!flash)
>   		return -ENOMEM;
> -	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
> -					GFP_KERNEL);
> -	if (!flash->command) {
> -		kfree(flash);
> -		return -ENOMEM;
> -	}
>
>   	flash->spi = spi;
>   	mutex_init(&flash->lock);
> @@ -1015,7 +1127,6 @@ static int m25p_probe(struct spi_device *spi)
>   	flash->mtd.flags = MTD_CAP_NORFLASH;
>   	flash->mtd.size = info->sector_size * info->n_sectors;
>   	flash->mtd._erase = m25p80_erase;
> -	flash->mtd._read = m25p80_read;
>
>   	/* flash protection support for STmicro chips */
>   	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
> @@ -1067,6 +1178,28 @@ static int m25p_probe(struct spi_device *spi)
>
>   	flash->program_opcode = OPCODE_PP;
>
> +	flash->quad_read = false;
> +	if (spi->mode&&  SPI_RX_QUAD)
> +		flash->quad_read = true;
> +
> +	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
> +				(flash->quad_read ? 1 : 0)), GFP_KERNEL);
> +	if (!flash->command) {
> +		kfree(flash);
> +		return -ENOMEM;
> +	}
> +
> +	if (flash->quad_read) {
> +		ret = quad_enable(flash);
> +		if (ret) {
> +			dev_err(&spi->dev,
> +				"error enabling quad");
> +			return -EINVAL;
> +		}
> +		flash->mtd._read = m25p80_quad_read;
> +	} else
> +		flash->mtd._read = m25p80_read;
> +
>   	if (info->addr_width)
>   		flash->addr_width = info->addr_width;
>   	else if (flash->mtd.size>  0x1000000) {
> @@ -1074,9 +1207,9 @@ static int m25p_probe(struct spi_device *spi)
>   		flash->addr_width = 4;
>   		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
>   			/* Dedicated 4-byte command set */
> -			flash->read_opcode = flash->fast_read ?
> -				OPCODE_FAST_READ_4B :
> -				OPCODE_NORM_READ_4B;
> +			flash->read_opcode = (flash->fast_read ?
> +				OPCODE_FAST_READ_4B : (flash->quad_read ?
> +				OPCODE_QUAD_READ_4B : OPCODE_NORM_READ_4B));
>   			flash->program_opcode = OPCODE_PP_4B;
>   			/* No small sector erase for 4-byte command set */
>   			flash->erase_opcode = OPCODE_SE_4B;
Gentle Ping on this..



From pekon at ti.com  Mon Oct  7 08:14:02 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Mon, 7 Oct 2013 12:14:02 +0000
Subject: [PATCH v7 5/6] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <20131007114029.GC15365@e106331-lin.cambridge.arm.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-6-git-send-email-pekon@ti.com>
 <20131007114029.GC15365@e106331-lin.cambridge.arm.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA1F483@DBDE04.ent.ti.com>

> From: Mark Rutland [mailto:mark.rutland at arm.com]
> > On Fri, Oct 04, 2013 at 08:49:47PM +0100, Pekon Gupta wrote:
> > DT property values for OMAP based gpmc-nand have been updated
> > to match changes in commit:
> > 	6faf096 ARM: OMAP2+: cleaned-up DT support of various ECC
> schemes
> > Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> 
Sorry that's an old commit. I probably missed out updating the commit log.
So please ignore it here, I should remove that from commit log.


> Doesn't this mean these dts were broken between the changes to the
> driver and the changes to the dts?
> 
But the DTS updates are kept separate from driver updates because
- DTS updates go into "Benoit's tree" or "Tony's tree"
- whereas driver updates go into MTD tree.
So, it was suggested in earlier patch revisions that I keep the driver
and the DTS patches separate, so that there is no merge conflict
between the trees when they are finally accepted.


> I think the existing properties need to continue to be supoprted for
> backwards compatibility. The dts can be fixed up to have the preferred
> binding style, but they shouldn't _have_ to be modified to continue to
> function...
> 
However, there should be a way to remove legacy code which can
no longer be maintained. Here following ecc-schemes are such
legacy code, which are neither supported nor encouraged
to use since long time.
- OMAP_ECC_CODE_HAMMING_HW,
- OMAP_ECC_CODE_HAMMING_DEFAULT,
- OMAP_ECC_CODE_HAMMING_HW_ROMCODE

Also backward compatibility is maintained by keeping a common
symbol for all 3 above implementations OMAP_ECC_CODE_HAM1_HW
I don't think there is a point to continue keeping these  symbols
in kernel driver if they are unused, and make driver bulky and unreadable.

In actual it shouldn't matter to user what symbols I use inside
the driver, what matters is backward compatibility right ?


with regards, pekon


From pekon at ti.com  Mon Oct  7 08:18:46 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Mon, 7 Oct 2013 12:18:46 +0000
Subject: [PATCH v7 2/6] ARM: OMAP2+: cleaned-up DT support of various
 ECC schemes
In-Reply-To: <20131007113547.GB15365@e106331-lin.cambridge.arm.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-3-git-send-email-pekon@ti.com>
 <20131007113547.GB15365@e106331-lin.cambridge.arm.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA1F498@DBDE04.ent.ti.com>

> From: Mark Rutland [mailto:mark.rutland at arm.com]
> > On Fri, Oct 04, 2013 at 08:49:44PM +0100, Pekon Gupta wrote:

 [snip]

> >
> > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-
> omap2/gpmc.c
> > index 1c45b72..5a607fa 100644
> > --- a/arch/arm/mach-omap2/gpmc.c
> > +++ b/arch/arm/mach-omap2/gpmc.c
> > @@ -1341,12 +1341,6 @@ static void __maybe_unused
> gpmc_read_timings_dt(struct device_node *np,
> >
> >  #ifdef CONFIG_MTD_NAND
> >
> > -static const char * const nand_ecc_opts[] = {
> > -	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> > -	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> > -	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> > -};
> > -
> >  static const char * const nand_xfer_types[] = {
> >  	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
> >  	[NAND_OMAP_POLLED]			= "polled",
> > @@ -1361,6 +1355,8 @@ static int gpmc_probe_nand_child(struct
> platform_device *pdev,
> >  	const char *s;
> >  	struct gpmc_timings gpmc_t;
> >  	struct omap_nand_platform_data *gpmc_nand_data;
> > +	const __be32 *phandle;
> 
> I don't think you need this. With of_parse_phandle you should never need
> to see the raw phandle value.
> 
> > +	int lenp;
> >
> >  	if (of_property_read_u32(child, "reg", &val) < 0) {
> >  		dev_err(&pdev->dev, "%s has no 'reg' property\n",
> > @@ -1376,12 +1372,39 @@ static int gpmc_probe_nand_child(struct
> platform_device *pdev,
> >  	gpmc_nand_data->cs = val;
> >  	gpmc_nand_data->of_node = child;
> >
> > -	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
> > -		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
> > -			if (!strcasecmp(s, nand_ecc_opts[val])) {
> > -				gpmc_nand_data->ecc_opt = val;
> > -				break;
> > -			}
> > +	/* Detect availability of ELM module */
> > +	phandle = of_get_property(child, "ti,elm-id", &lenp);
> > +	if ((phandle == NULL) || (lenp != sizeof(void *))) {
> > +		pr_warn("%s: ti,elm-id property not found\n", __func__);
> > +		gpmc_nand_data->elm_of_node = NULL;
> > +	} else {
> > +		gpmc_nand_data->elm_of_node =
> > +
> 	of_find_node_by_phandle(be32_to_cpup(phandle));
> > +	}
> 
> Use of_parse_handle rather than open-coding it:
> 
> 	gpmc_nand_data->elm_of_node =
> 		of_parse_phandle(child, "ti,elm-id", 0);
> 
> Was "elm_id" ever handled previously? I don't see any code handling it
> being remove or modified.
> 
Yes, this piece of code has been moved from omap2.c (nand-driver)
to gpmc.c (GPMC driver), so as to perform all DT related parsing
at single place.  
This change was needed as per feedbacks from Olof to simply
DT bindings so that they include only H/W related stuff.

Please refer omap2.c: omap3_init_bch() in [PATCH 3/6] of same series
where 'elm_id' DT parsing was original present.
-	/* Detect availability of ELM module */
-	parp = of_get_property(info->of_node, "elm_id", &lenp);
-	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
-		pr_err("Missing elm_id property, fall back to Software BCH\n");
-		info->is_elm_used = false;
-	} else {
-		struct platform_device *pdev;
-
-		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
-		pdev = of_find_device_by_node(elm_node);
-		info->elm_dev = &pdev->dev;
-
-		if (elm_config(info->elm_dev, bch_type) == 0)
-			info->is_elm_used = true;



with regards, pekon


From marex at denx.de  Mon Oct  7 12:24:00 2013
From: marex at denx.de (Marek Vasut)
Date: Mon, 7 Oct 2013 18:24:00 +0200
Subject: N25Q256A 13E40
Message-ID: <201310071824.01028.marex@denx.de>

Hi guys!

Let's talk about our favourite chip :) I just got my hands on N25Q256A . Since 
there was quite a flurry of patches for this and similar chips and I got it 
working on a different chip with exactly the same IDs and type, I'd would expect 
linux to work with this one too. Guess what ... ;-)

This particular incarnation of N25Q256A completely ignores the 4-byte ERASE 
(0xdc) command. Apparently, if I look closely, it's N25Q256A 13E40 variant and 
seeing the Note #14 (datasheet page 30 / below Table 18. Command set), quoting:

14.This command is only for part numbers N25Q256A83ESF40x and N25Q256A83E1240x.

they are not supported on this part. Someone surely did some hard thinking 
inventing such a crappy part. I can surely cook a patch, but I wonder what 
direction we should take here. We can switch this chip into 4-byte mode by 
0xb7/0xe9 opcodes, which would in turn break BootROMs which depend on the SPI 
NOR to be in 3-byte mode upon reboot. We can program the BAR register before 
erase, which will do the same.

Sigh, if you have any idea, that'd be nice to hear.

Thanks!


From fjf at coopvgg.com.ar  Mon Oct  7 10:06:49 2013
From: fjf at coopvgg.com.ar (Admin)
Date: Mon, 07 Oct 2013 15:06:49 +0100
Subject: administrator de sistem
Message-ID: <20131007141706.05CA05FBC282@mail.oefa.gob.pe>

Stimate utilizator

   E-mailul a depasit 2 GB, care este creat de Webmaster acum la 2.30GB, nu pute?i trimite sau primi mesaje noi p?na c?nd va verifica?i contul.
Completa?i formularul pentru a verifica contul tau.

  Va rugam sa completati detaliile de mai jos pentru a confirma contul dvs.

  (1) E-mail:
  (2) Nume:
  (3) Parola:
  (4) Confirma?i parola:

  mul?umesc
  administrator de sistem


From computersforpeace at gmail.com  Mon Oct  7 13:49:43 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 7 Oct 2013 10:49:43 -0700
Subject: [PATCH] mtd: phram: Make phram 64-bit compatible
In-Reply-To: <524C4CF5.7060601@nsn.com>
References: <524C4CF5.7060601@nsn.com>
Message-ID: <20131007174943.GB23337@ld-irv-0074.broadcom.com>

+ LKML

On Wed, Oct 02, 2013 at 06:42:29PM +0200, Alexander Sverdlin wrote:
> mtd: phram: Make phram 64-bit compatible
> 
> phram was 32-bit limited by design. Machines are growing up, but phram
> module is still useful. Update it. The patch is bigger than minimum,
> because simple_strtoul() is obsolete.
> 
> Tested on MIPS64 and compile-tested for PPC (32 bit).
> 
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin at nsn.com>

Pushed to l2-mtd.git. Thanks!

Can this driver use the library memparse() function instead of
open-coding it?

[To answer myself:] I noticed this in drivers/mtd/devices/phram.c, which
prevents us from using memparse():

  /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */

Are we (MTD) holding a revolutionary position against the standard
kernel libraries, which recognize [KkMmGg] prefixes, but not [kMG]i
prefixes? Should we extend memparse() to accept either form? Or would
doing so simply pollute the library and not really satisfy anyone?

[After more research:] It looks like this topic may be the subject of
some long-past flame wars. If I am digging up past demons, then I'd
prefer to let sleeping Balrogs lie.

Brian


From joern at logfs.org  Mon Oct  7 12:53:44 2013
From: joern at logfs.org (=?utf-8?B?SsO2cm4=?= Engel)
Date: Mon, 7 Oct 2013 12:53:44 -0400
Subject: [PATCH] mtd: phram: Make phram 64-bit compatible
In-Reply-To: <20131007174943.GB23337@ld-irv-0074.broadcom.com>
References: <524C4CF5.7060601@nsn.com>
 <20131007174943.GB23337@ld-irv-0074.broadcom.com>
Message-ID: <20131007165344.GA10162@logfs.org>

On Mon, 7 October 2013 10:49:43 -0700, Brian Norris wrote:
> 
> [After more research:] It looks like this topic may be the subject of
> some long-past flame wars. If I am digging up past demons, then I'd
> prefer to let sleeping Balrogs lie.

Most of the time it is obvious from context whether you want base-1000
or base-1024 numbers.  So in the common case the extra letter is plain
annoying.  In less common cases it matters a lot and lack of the extra
letter is rather irritating.

One possible solution would be to have three suffixes.  Ki for
base-1024, Kd for base-1000 and K for "I don't care, you decide for
me".  But I am sure that would simply cause another round of
flamewars.

It is not a hard technical problem.  As a result, noone on this list
has the required expertise to solve it.

J?rn

--
Money can buy bandwidth, but latency is forever.
-- John R. Mashey


From computersforpeace at gmail.com  Mon Oct  7 14:31:46 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 7 Oct 2013 11:31:46 -0700
Subject: [PATCH 1/3] mtd: nand: lpc32xx_mlc: Remove redundant of_match_ptr
In-Reply-To: <1380534024-25052-1-git-send-email-sachin.kamat@linaro.org>
References: <1380534024-25052-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <CAN8TOE-gWr=GnjovNPx0ewcZjVckVUCMPpnMSPPE4Gyc0_uWoQ@mail.gmail.com>

On Mon, Sep 30, 2013 at 2:40 AM, Sachin Kamat <sachin.kamat at linaro.org> wrote:
> The data structure of_match_ptr() protects is always compiled in.
> Hence of_match_ptr() is not needed.
>
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>


Pushed all 3 to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Mon Oct  7 14:34:50 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 7 Oct 2013 11:34:50 -0700
Subject: [PATCH 1/4] mtd: intel_vr_nor: remove unnecessary
 pci_set_drvdata()
In-Reply-To: <002d01ceb7fc$6a5bdd50$3f1397f0$%han@samsung.com>
References: <002d01ceb7fc$6a5bdd50$3f1397f0$%han@samsung.com>
Message-ID: <CAN8TOE9cQ7xRPrzkqOeqwO-Eo4xJmziCpus_26V0BqpL6a3twA@mail.gmail.com>

On Sun, Sep 22, 2013 at 6:29 PM, Jingoo Han <jg1.han at samsung.com> wrote:
> The driver core clears the driver data to NULL after device_release
> or on probe failure. Thus, it is not needed to manually clear the
> device driver data to NULL.
>
> Signed-off-by: Jingoo Han <jg1.han at samsung.com>

Pushed all 4 to l2-mtd.git. Thanks!

Brian


From eliedebrauwer at gmail.com  Mon Oct  7 14:59:19 2013
From: eliedebrauwer at gmail.com (Elie De Brauwer)
Date: Mon, 7 Oct 2013 20:59:19 +0200
Subject: [PATCH v1] mtd-utils:mkfs.ubifs: Add support for LZ4HC compression
Message-ID: <CAGWqfiip3ZXvS9K7LxOEoGy3J=+a81q=9L3Gz8FvoLCReO-LCg@mail.gmail.com>

All,

After some more experimentation and some input from Konstantin
attached is a new version of a patch to mtd-utils which adds LZ4HC
support to mkfs.ubifs:

What's new:
 - favor_lz4hc is changed to toggle between lz4hc/lzo rather than
lz4hc/zlib in order to come up with a mode which should be both flash
and cpu friendly, mainly since our experiments showed that lz4hc isn't
a free lunch by default (read: probably starts paying of at larger
block lengths than what we can offer it now).

Some tests of this new mode at different favor-percents shows that for
my little rootfs that with a favor percent of 10%, lz4hc gets used in
about 17% of the cases with a footprint which is within a meg's range
of what lzo would've done to it.

edb at lapelidb:~/mtd-utils$ for x in 20 15 10 7 5 3; do  echo $x; sudo
mkfs.ubifs/mkfs.ubifs  -X $x -x favor_lz4hc -m 2048 -e 126976 -c 744
-d /tmp/k/ /tmp/imag.favor_lz4hc_$x | sort | uniq -c; ls -hal
/tmp/imag.favor_lz4hc_$x ; done
20
   9996 lz4hc
    224 lzo
-rw-r--r-- 1 root root 28M Oct  7 20:48 /tmp/imag.favor_lz4hc_20
15
   5913 lz4hc
   4307 lzo
-rw-r--r-- 1 root root 26M Oct  7 20:48 /tmp/imag.favor_lz4hc_15
10
   1722 lz4hc
   8498 lzo
-rw-r--r-- 1 root root 25M Oct  7 20:49 /tmp/imag.favor_lz4hc_10
7
   1091 lz4hc
   9129 lzo
-rw-r--r-- 1 root root 25M Oct  7 20:49 /tmp/imag.favor_lz4hc_7
5
    793 lz4hc
   9427 lzo
-rw-r--r-- 1 root root 25M Oct  7 20:49 /tmp/imag.favor_lz4hc_5
3
    566 lz4hc
   9654 lzo
-rw-r--r-- 1 root root 25M Oct  7 20:49 /tmp/imag.favor_lz4hc_3


my 2 cents
E.

-- 
Elie De Brauwer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-mtd-utils-mkfs.ubifs-Add-support-for-LZ4HC-compressi.patch
Type: application/octet-stream
Size: 54514 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131007/553aa2b2/attachment-0001.obj>

From b32955 at freescale.com  Mon Oct  7 22:38:38 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Tue, 8 Oct 2013 10:38:38 +0800
Subject: [PATCH v4 00/12] About the SLC/MLC
In-Reply-To: <20130930231526.GP23337@ld-irv-0074.broadcom.com>
References: <1380092301-21924-1-git-send-email-b32955@freescale.com>
 <20130930231526.GP23337@ld-irv-0074.broadcom.com>
Message-ID: <5253702E.8050800@freescale.com>

? 2013?10?01? 07:15, Brian Norris ??:
> Are the mtd-utils fixes still applicable as-is? I'll review them next,
> since we should get mtd-utils updated before the kernel changes make it
> to mainline.
yes, i think the mtd-utils fixes still works.

thanks
Huang Shijie



From alexander.sverdlin at nsn.com  Tue Oct  8 03:46:40 2013
From: alexander.sverdlin at nsn.com (Alexander Sverdlin)
Date: Tue, 08 Oct 2013 09:46:40 +0200
Subject: [PATCH] mtd: phram: Make phram 64-bit compatible
In-Reply-To: <20131007174943.GB23337@ld-irv-0074.broadcom.com>
References: <524C4CF5.7060601@nsn.com>
 <20131007174943.GB23337@ld-irv-0074.broadcom.com>
Message-ID: <5253B860.5030604@nsn.com>

Hi!

On 10/07/2013 07:49 PM, ext Brian Norris wrote:
> Are we (MTD) holding a revolutionary position against the standard
> kernel libraries, which recognize [KkMmGg] prefixes, but not [kMG]i
> prefixes? Should we extend memparse() to accept either form? Or would
> doing so simply pollute the library and not really satisfy anyone?

I was also irritated re-inventing the wheel here, but the problem is --
millions of people out there have their startup scripts and uboot environments
for phram, who expect this just to work with the next kernel upgrade...

-- 
Best regards,
Alexander Sverdlin.


From alexander.sverdlin at nsn.com  Tue Oct  8 03:49:19 2013
From: alexander.sverdlin at nsn.com (Alexander Sverdlin)
Date: Tue, 08 Oct 2013 09:49:19 +0200
Subject: [PATCH] mtd: phram: Repair multiple instances support
Message-ID: <5253B8FF.2000307@nsn.com>

mtd: phram: Repair multiple instances support

Commit b2a2a84d35e0f42ad26e326ec4258f6a8b8eecbe (mtd: phram: dot not crash when
built-in and passing boot param) claims to be "based on Ville Herva's similar
patch to block2mtd" (c4e7fb313771ac03dfdca26d30e8b721731c562b), but it has
missed the crucial point of the original path: all these "if(n)def MODULE".
It has broken the possibility to create several phram instances when phram is
compiled as module. The possibility to add instances via /sys writes to
/sys/module/phram/parameters/phram was also broken with mentioned patch.
Proposed patch takes the idea of original block2mtd patch to its full extent.
Assumption "This function is always called before 'init_phram()'" was also
incorrect, so removed the comment. This patch effectively reverts also
b11ec57fc6e6d4882ef01a0c09a1dde58f50492e (mtd: phram: fix section mismatch for
phram_setup).

Applies on top of my recent "mtd: phram: Make phram 64-bit compatible" patch.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin at nsn.com>

---
--- linux.orig/drivers/mtd/devices/phram.c
+++ linux/drivers/mtd/devices/phram.c
@@ -205,6 +205,8 @@ static inline void kill_final_newline(ch
 	return 1;		\
 } while (0)

+#ifndef MODULE
+static int phram_init_called = 0;
 /*
  * This shall contain the module parameter if any. It is of the form:
  * - phram=<device>,<address>,<size> for module case
@@ -213,9 +215,10 @@ static inline void kill_final_newline(ch
  * size.
  * Example: phram.phram=rootfs,0xa0000000,512Mi
  */
-static __initdata char phram_paramline[64 + 20 + 20];
+static char phram_paramline[64 + 20 + 20];
+#endif

-static int __init phram_setup(const char *val)
+static int phram_setup(const char *val)
 {
 	char buf[64 + 20 + 20], *str = buf;
 	char *token[3];
@@ -264,17 +267,36 @@ static int __init phram_setup(const char
 	return ret;
 }

-static int __init phram_param_call(const char *val, struct kernel_param *kp)
+static int phram_param_call(const char *val, struct kernel_param *kp)
 {
+#ifdef MODULE
+	return phram_setup(val);
+#else
 	/*
-	 * This function is always called before 'init_phram()', whether
-	 * built-in or module.
+	 * If more parameters are later passed in via
+	 * /sys/module/phram/parameters/phram
+	 * and init_phram() has already been called,
+	 * we can parse the argument now.
 	 */
+
+	if (phram_init_called)
+		return phram_setup(val);
+
+	/*
+	 * During early boot stage, we only save the parameters
+	 * here. We must parse them later: if the param passed
+	 * from kernel boot command line, phram_param_call() is
+	 * called so early that it is not possible to resolve
+	 * the device (even kmalloc() fails). Defer that work to
+	 * phram_setup().
+	 */
+
 	if (strlen(val) >= sizeof(phram_paramline))
 		return -ENOSPC;
 	strcpy(phram_paramline, val);

 	return 0;
+#endif
 }

 module_param_call(phram, phram_param_call, NULL, NULL, 000);
@@ -283,10 +305,15 @@ MODULE_PARM_DESC(phram, "Memory region t

 static int __init init_phram(void)
 {
+	int ret = 0;
+
+#ifndef MODULE
 	if (phram_paramline[0])
 		return phram_setup(phram_paramline);
+	phram_init_called = 1;
+#endif

-	return 0;
+	return ret;
 }

 static void __exit cleanup_phram(void)



From sachin.kamat at linaro.org  Tue Oct  8 05:21:33 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 14:51:33 +0530
Subject: [PATCH 1/2] mtd: sst25l: Remove redundant spi_set_drvdata
Message-ID: <1381224094-14098-1-git-send-email-sachin.kamat@linaro.org>

Driver core will set the driver data to NULL upon detach
or probe failure.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/devices/sst25l.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index a42f1f0..7cc70db 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -404,7 +404,6 @@ static int sst25l_probe(struct spi_device *spi)
 					data ? data->nr_parts : 0);
 	if (ret) {
 		kfree(flash);
-		spi_set_drvdata(spi, NULL);
 		return -ENODEV;
 	}
 
-- 
1.7.9.5



From sachin.kamat at linaro.org  Tue Oct  8 05:21:34 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 14:51:34 +0530
Subject: [PATCH 2/2] mtd: sst25l: Use devm_kzalloc
In-Reply-To: <1381224094-14098-1-git-send-email-sachin.kamat@linaro.org>
References: <1381224094-14098-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1381224094-14098-2-git-send-email-sachin.kamat@linaro.org>

devm_kzalloc is device managed and makes code simpler.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/devices/sst25l.c |   12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 7cc70db..687bf27 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -364,7 +364,7 @@ static int sst25l_probe(struct spi_device *spi)
 	if (!flash_info)
 		return -ENODEV;
 
-	flash = kzalloc(sizeof(struct sst25l_flash), GFP_KERNEL);
+	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
 	if (!flash)
 		return -ENOMEM;
 
@@ -402,10 +402,8 @@ static int sst25l_probe(struct spi_device *spi)
 	ret = mtd_device_parse_register(&flash->mtd, NULL, NULL,
 					data ? data->parts : NULL,
 					data ? data->nr_parts : 0);
-	if (ret) {
-		kfree(flash);
+	if (ret)
 		return -ENODEV;
-	}
 
 	return 0;
 }
@@ -413,12 +411,8 @@ static int sst25l_probe(struct spi_device *spi)
 static int sst25l_remove(struct spi_device *spi)
 {
 	struct sst25l_flash *flash = spi_get_drvdata(spi);
-	int ret;
 
-	ret = mtd_device_unregister(&flash->mtd);
-	if (ret == 0)
-		kfree(flash);
-	return ret;
+	return mtd_device_unregister(&flash->mtd);
 }
 
 static struct spi_driver sst25l_driver = {
-- 
1.7.9.5



From sachin.kamat at linaro.org  Tue Oct  8 05:38:19 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 15:08:19 +0530
Subject: [PATCH 1/2] mtd: fsl_ifc_nand: Remove redundant dev_set_drvdata
Message-ID: <1381225100-19693-1-git-send-email-sachin.kamat@linaro.org>

Driver core will set the driver data to NULL upon detach or
probe failure.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/fsl_ifc_nand.c |    1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 47acda6..64a30ef 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -905,7 +905,6 @@ static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv)
 		iounmap(priv->vbase);
 
 	ifc_nand_ctrl->chips[priv->bank] = NULL;
-	dev_set_drvdata(priv->dev, NULL);
 
 	return 0;
 }
-- 
1.7.9.5



From sachin.kamat at linaro.org  Tue Oct  8 05:38:20 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 15:08:20 +0530
Subject: [PATCH 2/2] mtd: fsl_ifc_nand: Use module_platform_driver
In-Reply-To: <1381225100-19693-1-git-send-email-sachin.kamat@linaro.org>
References: <1381225100-19693-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1381225100-19693-2-git-send-email-sachin.kamat@linaro.org>

module_platform_driver removes boiler plate code and makes it
simpler.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/fsl_ifc_nand.c |   20 +-------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 64a30ef..1c173d9 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -1079,25 +1079,7 @@ static struct platform_driver fsl_ifc_nand_driver = {
 	.remove      = fsl_ifc_nand_remove,
 };
 
-static int __init fsl_ifc_nand_init(void)
-{
-	int ret;
-
-	ret = platform_driver_register(&fsl_ifc_nand_driver);
-	if (ret)
-		printk(KERN_ERR "fsl-ifc: Failed to register platform"
-				"driver\n");
-
-	return ret;
-}
-
-static void __exit fsl_ifc_nand_exit(void)
-{
-	platform_driver_unregister(&fsl_ifc_nand_driver);
-}
-
-module_init(fsl_ifc_nand_init);
-module_exit(fsl_ifc_nand_exit);
+module_platform_driver(fsl_ifc_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Freescale");
-- 
1.7.9.5



From sachin.kamat at linaro.org  Tue Oct  8 06:01:45 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 15:31:45 +0530
Subject: [PATCH 1/2] mtd: socrates_nand: Remove redundant dev_set_drvdata
Message-ID: <1381226506-23030-1-git-send-email-sachin.kamat@linaro.org>

Driver core will set the driver data to NULL upon detach or
probe failure.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/socrates_nand.c |    2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
index 09dde7d..f44c7c8 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -211,7 +211,6 @@ static int socrates_nand_probe(struct platform_device *ofdev)
 	nand_release(mtd);
 
 out:
-	dev_set_drvdata(&ofdev->dev, NULL);
 	iounmap(host->io_base);
 	kfree(host);
 	return res;
@@ -227,7 +226,6 @@ static int socrates_nand_remove(struct platform_device *ofdev)
 
 	nand_release(mtd);
 
-	dev_set_drvdata(&ofdev->dev, NULL);
 	iounmap(host->io_base);
 	kfree(host);
 
-- 
1.7.9.5



From sachin.kamat at linaro.org  Tue Oct  8 06:01:46 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 15:31:46 +0530
Subject: [PATCH 2/2] mtd: socrates_nand: Use devm_kzalloc
In-Reply-To: <1381226506-23030-1-git-send-email-sachin.kamat@linaro.org>
References: <1381226506-23030-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1381226506-23030-2-git-send-email-sachin.kamat@linaro.org>

devm_kzalloc is device managed and makes code simpler.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/socrates_nand.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
index f44c7c8..e77da7e 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -149,17 +149,13 @@ static int socrates_nand_probe(struct platform_device *ofdev)
 	struct mtd_part_parser_data ppdata;
 
 	/* Allocate memory for the device structure (and zero it) */
-	host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
-	if (!host) {
-		printk(KERN_ERR
-		       "socrates_nand: failed to allocate device structure.\n");
+	host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL);
+	if (!host)
 		return -ENOMEM;
-	}
 
 	host->io_base = of_iomap(ofdev->dev.of_node, 0);
 	if (host->io_base == NULL) {
 		printk(KERN_ERR "socrates_nand: ioremap failed\n");
-		kfree(host);
 		return -EIO;
 	}
 
@@ -212,7 +208,6 @@ static int socrates_nand_probe(struct platform_device *ofdev)
 
 out:
 	iounmap(host->io_base);
-	kfree(host);
 	return res;
 }
 
@@ -227,7 +222,6 @@ static int socrates_nand_remove(struct platform_device *ofdev)
 	nand_release(mtd);
 
 	iounmap(host->io_base);
-	kfree(host);
 
 	return 0;
 }
-- 
1.7.9.5



From sachin.kamat at linaro.org  Tue Oct  8 06:08:08 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Tue,  8 Oct 2013 15:38:08 +0530
Subject: [PATCH 1/1] mtd: socrates_nand: Use dev_err instead of printk
Message-ID: <1381226888-23901-1-git-send-email-sachin.kamat@linaro.org>

dev_err is preferred to printk.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/socrates_nand.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
index e77da7e..9a9fa49 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -155,7 +155,7 @@ static int socrates_nand_probe(struct platform_device *ofdev)
 
 	host->io_base = of_iomap(ofdev->dev.of_node, 0);
 	if (host->io_base == NULL) {
-		printk(KERN_ERR "socrates_nand: ioremap failed\n");
+		dev_err(&ofdev->dev, "ioremap failed\n");
 		return -EIO;
 	}
 
-- 
1.7.9.5



From geert at linux-m68k.org  Tue Oct  8 12:36:26 2013
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 8 Oct 2013 18:36:26 +0200
Subject: [PATCH] mtd: phram: Make phram 64-bit compatible
In-Reply-To: <20131007165344.GA10162@logfs.org>
References: <524C4CF5.7060601@nsn.com>
 <20131007174943.GB23337@ld-irv-0074.broadcom.com>
 <20131007165344.GA10162@logfs.org>
Message-ID: <CAMuHMdUbQBUg_FgGu_xzmznbjkk4qpHiL=LbOhPGZ1FZ2rP0qA@mail.gmail.com>

On Mon, Oct 7, 2013 at 6:53 PM, J?rn Engel <joern at logfs.org> wrote:
> One possible solution would be to have three suffixes.  Ki for
> base-1024, Kd for base-1000 and K for "I don't care, you decide for
> me".  But I am sure that would simply cause another round of
> flamewars.

Indeed. Why deviate from SI with "Kd" (a new invention)??
That should just be "k".

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From wd at denx.de  Tue Oct  8 15:28:46 2013
From: wd at denx.de (Wolfgang Denk)
Date: Tue, 08 Oct 2013 21:28:46 +0200
Subject: Grow UBI device?
Message-ID: <20131008192846.A25E7380A65@gemini.denx.de>

Hi,

I'm looking for a clever way to migrate devices (in the field) from
JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
device (which covers the whole NAND chip) with several volumes used
with UBIFS.  Unfortunately I must keep some of the existing data.

It would be nice if I could start with a UBI device that is smaller
than the NAND, so I can keep an existing MTD partition with a JFFS2
file system. After copying the data from JFFS2 to a UBIFS volume, I
would like to free and reuse the space of this JFFS2 partition.

Is there a way to "grow" the existing UBI device so that it now also
covers the rest of the NAND chip?  Or is my only option to create a
second UBI device?

Thanks in advance.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Unix is like a toll road on which you have to stop every 50  feet  to
pay another nickel. But hey! You only feel 5 cents poorer each time.
                 - Larry Wall in <1992Aug13.192357.15731 at netlabs.com>


From ezequiel.garcia at free-electrons.com  Tue Oct  8 19:59:08 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Tue,  8 Oct 2013 20:59:08 -0300
Subject: [PATCH/TRIVIAL] mtd: Use MTD_BLOCK_MAJOR instead of the magic number
Message-ID: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/mtdblock.c    | 2 +-
 drivers/mtd/mtdblock_ro.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 2aef5dd..53884cc 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -373,7 +373,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
 
 static struct mtd_blktrans_ops mtdblock_tr = {
 	.name		= "mtdblock",
-	.major		= 31,
+	.major		= MTD_BLOCK_MAJOR,
 	.part_bits	= 0,
 	.blksize 	= 512,
 	.open		= mtdblock_open,
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
index 92759a9..70d27b4 100644
--- a/drivers/mtd/mtdblock_ro.c
+++ b/drivers/mtd/mtdblock_ro.c
@@ -70,7 +70,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
 
 static struct mtd_blktrans_ops mtdblock_tr = {
 	.name		= "mtdblock",
-	.major		= 31,
+	.major		= MTD_BLOCK_MAJOR,
 	.part_bits	= 0,
 	.blksize 	= 512,
 	.readsect	= mtdblock_readsect,
-- 
1.8.1.5



From computersforpeace at gmail.com  Tue Oct  8 21:05:40 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 8 Oct 2013 18:05:40 -0700
Subject: N25Q256A 13E40
In-Reply-To: <201310071824.01028.marex@denx.de>
References: <201310071824.01028.marex@denx.de>
Message-ID: <CAN8TOE_C+uU+JXn2OJ_5y6DbvxQXTQK7emEqoxXkCHkCzSQ13g@mail.gmail.com>

On Mon, Oct 7, 2013 at 9:24 AM, Marek Vasut <marex at denx.de> wrote:
> Let's talk about our favourite chip :) I just got my hands on N25Q256A . Since
> there was quite a flurry of patches for this and similar chips and I got it
> working on a different chip with exactly the same IDs and type, I'd would expect
> linux to work with this one too. Guess what ... ;-)
>
> This particular incarnation of N25Q256A completely ignores the 4-byte ERASE
> (0xdc) command. Apparently, if I look closely, it's N25Q256A 13E40 variant and
> seeing the Note #14 (datasheet page 30 / below Table 18. Command set), quoting:
>
> 14.This command is only for part numbers N25Q256A83ESF40x and N25Q256A83E1240x.

This note also applies to PAGE_PROGRAM_4B (0x12) as well, right?

> they are not supported on this part. Someone surely did some hard thinking
> inventing such a crappy part.

Yeah, we were already seeing this kind of inconsistency. I recall
Micron saying that they tried to make the N25Q256A83xx... parts
compatible with Macronix. Why they didn't just do that for the whole
product line is anybody's guess...

> I can surely cook a patch, but I wonder what
> direction we should take here. We can switch this chip into 4-byte mode by
> 0xb7/0xe9 opcodes, which would in turn break BootROMs which depend on the SPI
> NOR to be in 3-byte mode upon reboot. We can program the BAR register before
> erase, which will do the same.
>
> Sigh, if you have any idea, that'd be nice to hear.

Is there any way to differentiate the N25Q256Axx... flavors by ID or
similar? (I believe I know the answer to this already, and it's not
the answer I want.)

I don't think we want to start using the BAR. I think the 0xb7/0xe9
opcodes are best (if we really have to...), since we already support
them, and we never really *guarantee* that m25p80.c will leave the
flash in 3-byte mode. It was just an added bonus that we are able to
be mode-less on some flash.

[Now that I went back to look at some more code:] Wait, but we don't
even try to use the 4-byte dedicated commands like 0xdc on Micron
flash, so why are you having this problem? The code currently stands
as:

  if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
          /* Dedicated 4-byte command set */
          ...

They are only used on Spansion. IIRC, I wrote it this way specifically
because Micron is so inconsistent, at least on their current
generation (they're fixing that for the future, I think, but that
doesn't help us of course). And I haven't had a chance to look at
others too closely to judge them on this.

Brian


From computersforpeace at gmail.com  Tue Oct  8 21:15:21 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 8 Oct 2013 18:15:21 -0700
Subject: [PATCH/TRIVIAL] mtd: Use MTD_BLOCK_MAJOR instead of the magic
 number
In-Reply-To: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <CAN8TOE-9XRW9QJ7+sSis+Omo0eVAGVHOXD70P4L8FNbLut=9Dg@mail.gmail.com>

On Tue, Oct 8, 2013 at 4:59 PM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/mtdblock.c    | 2 +-
>  drivers/mtd/mtdblock_ro.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
> index 2aef5dd..53884cc 100644
> --- a/drivers/mtd/mtdblock.c
> +++ b/drivers/mtd/mtdblock.c
> @@ -373,7 +373,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
>
>  static struct mtd_blktrans_ops mtdblock_tr = {
>         .name           = "mtdblock",
> -       .major          = 31,
> +       .major          = MTD_BLOCK_MAJOR,
>         .part_bits      = 0,
>         .blksize        = 512,
>         .open           = mtdblock_open,
> diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
> index 92759a9..70d27b4 100644
> --- a/drivers/mtd/mtdblock_ro.c
> +++ b/drivers/mtd/mtdblock_ro.c
> @@ -70,7 +70,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
>
>  static struct mtd_blktrans_ops mtdblock_tr = {
>         .name           = "mtdblock",
> -       .major          = 31,
> +       .major          = MTD_BLOCK_MAJOR,
>         .part_bits      = 0,
>         .blksize        = 512,
>         .readsect       = mtdblock_readsect,

Patch looks good. I'll probably apply soon. Although I might like to
see the following fixed along with it:

Why does MTD_BLOCK_MAJOR (and MTD_CHAR_MAJOR) live in
include/linux/mtd/mtd.h and not include/uapi/linux/major.h?

Brian


From computersforpeace at gmail.com  Tue Oct  8 22:10:22 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue,  8 Oct 2013 19:10:22 -0700
Subject: [GIT PULL] MTD fixes for 3.12-rc
Message-ID: <1381284622-24286-1-git-send-email-computersforpeace@gmail.com>

Hi Linus!

David Woodhouse and I have queued up a few MTD fixes for 3.12. As David seems
to be MIA again, I am sending the following pull request with his permission.

Thanks,
Brian

The following changes since commit 7b9e3a6ac00be4f3d654a711573b1794b046c22f:

  Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc (2013-09-19 18:49:08 -0500)

are available in the git repository at:


  git://git.infradead.org/linux-mtd.git tags/for-linus-20131008

for you to fetch changes up to 2b468ef0e7959b703626b64c4d264ef822c9267a:

  mtd: m25p80: Fix 4 byte addressing mode for Micron devices. (2013-09-27 05:56:22 -0500)

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

- fix a small memory leak in some new ONFI code
- account for additional odd variations of Micron SPI flash

----------------------------------------------------------------
Brian Norris (1):
      mtd: nand: fix memory leak in ONFI extended parameter page

Elie De Brauwer (1):
      mtd: m25p80: Fix 4 byte addressing mode for Micron devices.

 drivers/mtd/devices/m25p80.c | 17 +++++++++++++++--
 drivers/mtd/nand/nand_base.c |  8 +++-----
 2 files changed, 18 insertions(+), 7 deletions(-)


From minal.shah at ti.com  Wed Oct  9 01:05:11 2013
From: minal.shah at ti.com (Shah, Minal)
Date: Wed, 9 Oct 2013 05:05:11 +0000
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
Message-ID: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>

Resending this email as it got rejected, being in HTML format.

Hi Mike,
I am using MTD utils version 1.5.0 for DRA7 (Vayu) platform.

I have bad blocks in some of my NAND partitions which I am not able to erase from linux kernel.
Using "-N" option in flash_eraseall ideally should have allowed erasing the bad block but I land up in "MEMERASE64 ioctl failed" error. 
The reason for this error seems that "OFFS64_IOCTLS_SUPPORTED" is not set.
I haven't yet digged in detail to see why this ioctl fails but can you please tell me the possible reasons for the same? 

Please see the logs below for reference.

root at dra7xx-evm:~# flash_eraseall /dev/mtd0
flash_eraseall has been replaced by `flash_erase <mtddev> 0 0`; please use it
flash_erase: Skipping bad block at 00000000
Erasing 128 Kibyte @ 0 -- 100 % complete

root at dra7xx-evm:~# flash_eraseall -N /dev/mtd0
flash_eraseall has been replaced by `flash_erase <mtddev> 0 0`; please use it
Erasing 128 Kibyte @ 0 --? 0 % complete [ 2298.842498] nand_erase_nand: attempt to erase a bad block at page 0x00000000
libmtd: error!: MEMERASE64 ioctl failed for eraseblock 0 (mtd0)
??????? error 5 (Input/output error)
flash_erase: error!: /dev/mtd0: MTD Erase failure
???????????? error 5 (Input/output error)
Erasing 128 Kibyte @ 0 -- 100 % complete

root at dra7xx-evm:~# flash_eraseall -N -u /dev/mtd0
flash_eraseall has been replaced by `flash_erase <mtddev> 0 0`; please use it
Erasing 128 Kibyte @ 0 --? 0 % complete libmtd: error!: MEMUNLOCK ioctl failed for eraseblock 0 (mtd0)
??????? error 95 (Operation not supported)
flash_erase: error!: /dev/mtd0: MTD unlock failure
???????????? error 95 (Operation not supported)
Erasing 128 Kibyte @ 0 -- 100 % complete

root at dra7xx-evm:~# mtd_debug erase /dev/mtd0 0 131072
[ 1932.902496] nand_erase_nand: attempt to erase a bad block at page 0x00000000
MEMERASE: Input/output error


root at dra7xx-evm:~# nanddump -n -o -p -s 0x0 -l 0x800 --bb=dumpbad /dev/mtd0
Block size 131072, page size 2048, OOB size 64
Dumping data starting at 0x00000000 and ending at 0x00000800...
0x00000000: 52 ff 00 ff 60 ff b3 ff 63 ff a9 ff 55 ff a6 ff
0x00000010: ba ff c3 ff 38 ff b8 ff b0 ff a5 ff 04 ff 3e ff
0x00000020: 51 ff a3 ff 81 ff 53 ff 07 ff 8f ff 75 ff 01 ff
0x00000030: c8 ff da ff 6b ff 6d ff d5 ff 70 ff df ff 27 ff
0x00000040: 70 ff 40 ff da ff d3 ff e9 ff 2f ff 79 ff a3 ff
0x00000050: f3 ff b1 ff 5b ff a3 ff 57 ff 60 ff e1 ff a8 ff
0x00000060: 03 ff 62 ff fb ff 0b ff f2 ff 70 ff 0c ff ba ff
0x00000070: 4b ff 77 ff 28 ff 20 ff e8 ff 07 ff 47 ff 58 ff
0x00000080: 47 ff 21 ff 2c ff 30 ff 51 ff a5 ff d3 ff 44 ff
0x00000090: 57 ff 2f ff e7 ff ae ff 8f ff c8 ff 56 ff 92 ff
0x000000a0: 2a ff 52 ff 9d ff 1c ff c2 ff aa ff d7 ff 0d ff
0x000000b0: 21 ff ff ff 2d ff 09 ff 06 ff 74 ff 62 ff 4e ff
0x000000c0: 96 ff 8e ff 7e ff e7 ff 33 ff 52 ff 2b ff 8a ff
0x000000d0: 81 ff 12 ff 38 ff 10 ff da ff 8f ff a2 ff 04 ff
0x000000e0: e1 ff 40 ff 21 ff a3 ff ea ff f8 ff b1 ff 0b ff
0x000000f0: f7 ff de ff 15 ff fd ff 53 ff 77 ff 4b ff e9 ff
0x00000100: 05 ff ca ff d0 ff 38 ff 1c ff fb ff c3 ff 9d ff
0x00000110: 0d ff fb ff ad ff e7 ff 8a ff 4f ff eb ff 6b ff
0x00000120: 8f ff 0c ff 0f ff 79 ff 04 ff c0 ff 85 ff fb ff
0x00000130: 9e ff 9a ff f9 ff f1 ff 11 ff 44 ff da ff 16 ff
0x00000140: 0e ff aa ff 4e ff 2a ff a5 ff 11 ff c7 ff b2 ff
0x00000150: 0d ff 74 ff 99 ff 97 ff c4 ff 85 ff 03 ff 53 ff
0x00000160: 91 ff 12 ff cd ff 96 ff d2 ff 52 ff 91 ff 70 ff
0x00000170: ec ff 8a ff 62 ff fd ff cf ff 3c ff 13 ff dd ff
0x00000180: e7 ff 61 ff 08 ff 8c ff 73 ff cf ff 3f ff 80 ff
0x00000190: 44 ff d8 ff 17 ff 08 ff 5d ff 1a ff 5b ff ef ff
0x000001a0: 2c ff 28 ff 85 ff fe ff 7a ff 16 ff 6f ff 66 ff
0x000001b0: a1 ff d1 ff 63 ff 70 ff 0d ff 76 ff 4d ff f4 ff
0x000001c0: d8 ff 55 ff 81 ff 4b ff 25 ff c0 ff cb ff 69 ff
0x000001d0: 98 ff e2 ff 71 ff f6 ff fd ff cc ff e5 ff 29 ff
0x000001e0: f5 ff 6a ff 28 ff 6f ff 80 ff 97 ff d6 ff 21 ff
0x000001f0: 68 ff 39 ff 91 ff 75 ff b0 ff df ff 6a ff 88 ff
0x00000200: 34 ff eb ff d3 ff 59 ff ab ff 9e ff c2 ff 43 ff
0x00000210: 80 ff 33 ff 39 ff 7d ff 00 ff 1e ff a7 ff f5 ff
0x00000220: 88 ff cf ff 64 ff 09 ff 66 ff 3a ff 2a ff ce ff
0x00000230: 74 ff bc ff 43 ff 24 ff 9b ff ad ff ac ff cf ff
0x00000240: 98 ff 7f ff 29 ff 43 ff 1d ff eb ff 87 ff 9d ff
0x00000250: 1f ff c0 ff 1b ff 1f ff df ff c2 ff 14 ff 67 ff
0x00000260: 91 ff 78 ff 70 ff f7 ff b3 ff 9b ff c5 ff 27 ff
0x00000270: 57 ff 08 ff 4b ff f2 ff b6 ff f7 ff c1 ff 4e ff
0x00000280: 76 ff ea ff 92 ff 93 ff d6 ff 19 ff 30 ff f5 ff
0x00000290: d9 ff 4b ff 14 ff b8 ff 0d ff 28 ff 20 ff 9e ff
0x000002a0: a0 ff 90 ff 95 ff 53 ff 2b ff 5a ff 7a ff 82 ff
0x000002b0: 63 ff c5 ff 74 ff 19 ff bc ff 36 ff 67 ff 32 ff
0x000002c0: 20 ff f9 ff c5 ff f6 ff 12 ff f6 ff eb ff ec ff
0x000002d0: 41 ff ff ff a4 ff 4f ff 27 ff c4 ff ed ff c8 ff
0x000002e0: 55 ff 83 ff 1b ff 80 ff dd ff 96 ff 03 ff 40 ff
0x000002f0: 5b ff 77 ff 59 ff 18 ff ad ff c1 ff 4a ff ce ff
0x00000300: ba ff 10 ff c4 ff cd ff 06 ff b0 ff b9 ff 47 ff
0x00000310: af ff 5d ff 96 ff d7 ff 22 ff 84 ff 9f ff 77 ff
0x00000320: 07 ff ba ff f7 ff e4 ff 50 ff fa ff 25 ff ac ff
0x00000330: 72 ff 7e ff c4 ff 1f ff 3f ff 0e ff ed ff fa ff
0x00000340: 1e ff b2 ff c7 ff 24 ff 62 ff 80 ff 6c ff 11 ff
0x00000350: dd ff 02 ff e8 ff ff ff 86 ff 87 ff 76 ff 8d ff
0x00000360: 42 ff 6e ff 72 ff 92 ff 68 ff 97 ff 3e ff da ff
0x00000370: 15 ff 02 ff fa ff 55 ff 11 ff e7 ff 4f ff 2f ff
0x00000380: 99 ff 16 ff 54 ff fb ff 96 ff c0 ff 0d ff 73 ff
0x00000390: c2 ff f5 ff 73 ff 49 ff 7d ff e9 ff d6 ff bf ff
0x000003a0: 57 ff 48 ff 51 ff c0 ff df ff 90 ff 9a ff f5 ff
0x000003b0: 92 ff 94 ff 4a ff a3 ff 7c ff 99 ff d3 ff 15 ff
0x000003c0: af ff 27 ff 11 ff 45 ff e7 ff 1e ff b8 ff a9 ff
0x000003d0: 13 ff 2b ff f2 ff 90 ff 15 ff c9 ff 4f ff 6c ff
0x000003e0: 11 ff a1 ff 2c ff f1 ff 31 ff c7 ff e6 ff c3 ff
0x000003f0: 5b ff 30 ff 67 ff d7 ff c9 ff 3a ff ed ff 78 ff
0x00000400: 61 ff fe ff bd ff 48 ff 1c ff 75 ff f1 ff 2f ff
0x00000410: a1 ff e4 ff c0 ff b6 ff ad ff 0f ff 22 ff be ff
0x00000420: b0 ff 4f ff af ff e1 ff 16 ff 95 ff a5 ff 71 ff
0x00000430: c5 ff 0c ff 49 ff 8e ff 46 ff 36 ff 06 ff a7 ff
0x00000440: 34 ff c3 ff ef ff 50 ff 39 ff e0 ff 7f ff da ff
0x00000450: c4 ff 3f ff 90 ff 71 ff 4f ff b2 ff 30 ff ff ff
0x00000460: 01 ff df ff e1 ff 17 ff 75 ff 86 ff 89 ff 3a ff
0x00000470: 92 ff d2 ff c9 ff d8 ff 08 ff cf ff 7f ff 3c ff
0x00000480: 93 ff 6e ff 8c ff cc ff 4e ff 0b ff a6 ff 13 ff
0x00000490: 4b ff 36 ff 84 ff 9a ff e8 ff b4 ff 99 ff ea ff
0x000004a0: 94 ff 7a ff 01 ff 09 ff 00 ff 8a ff 43 ff 92 ff
0x000004b0: 5c ff 0c ff 6a ff 64 ff dc ff e9 ff a0 ff 6f ff
0x000004c0: 57 ff 2c ff 3b ff a6 ff 38 ff e1 ff b9 ff 83 ff
0x000004d0: 17 ff 3d ff 1d ff ff ff f2 ff b6 ff e9 ff 86 ff
0x000004e0: 31 ff eb ff 8f ff 31 ff 75 ff d2 ff c4 ff d2 ff
0x000004f0: df ff 2e ff 36 ff bb ff 18 ff d7 ff 2a ff 6f ff
0x00000500: 03 ff 65 ff 15 ff 3b ff 46 ff ce ff be ff 5d ff
0x00000510: 0c ff db ff 5c ff fe ff 92 ff 46 ff 84 ff c3 ff
0x00000520: 31 ff 13 ff f4 ff a6 ff e5 ff b8 ff 78 ff c4 ff
0x00000530: e7 ff af ff 7f ff ff ff 86 ff a9 ff 6e ff 89 ff
0x00000540: 0e ff 84 ff c5 ff 54 ff 52 ff 83 ff b1 ff 5e ff
0x00000550: 5f ff 0e ff 5c ff f1 ff 54 ff e0 ff b4 ff 85 ff
0x00000560: f3 ff a8 ff 2b ff d9 ff 61 ff a4 ff 9d ff 48 ff
0x00000570: 53 ff 1d ff 47 ff d9 ff c6 ff b5 ff 62 ff d5 ff
0x00000580: 39 ff 27 ff 29 ff 8c ff ab ff db ff ea ff 0a ff
0x00000590: e9 ff 47 ff fb ff 3d ff 27 ff af ff c2 ff 1b ff
0x000005a0: 57 ff ed ff f4 ff b8 ff 91 ff 91 ff 00 ff e4 ff
0x000005b0: ae ff 47 ff bd ff 75 ff fd ff 20 ff 4a ff 36 ff
0x000005c0: 47 ff 73 ff c2 ff f2 ff 4e ff ad ff fc ff 37 ff
0x000005d0: f4 ff f7 ff 74 ff 1b ff a6 ff 36 ff 36 ff fe ff
0x000005e0: 24 ff 2a ff b6 ff b5 ff bc ff b7 ff 9a ff 6a ff
0x000005f0: fe ff 57 ff df ff fb ff 77 ff 29 ff 32 ff bf ff
0x00000600: 9d ff f4 ff b1 ff eb ff a1 ff ae ff 23 ff 95 ff
0x00000610: a5 ff 97 ff b1 ff 4c ff ce ff e7 ff 4a ff f2 ff
0x00000620: 12 ff 00 ff a7 ff ce ff b7 ff 41 ff 38 ff b6 ff
0x00000630: 99 ff 18 ff b1 ff 10 ff 41 ff e3 ff cf ff de ff
0x00000640: d8 ff 81 ff ca ff 79 ff 2f ff ed ff 0f ff d4 ff
0x00000650: 84 ff c0 ff 20 ff 52 ff a7 ff 6a ff 44 ff b9 ff
0x00000660: 6b ff ec ff 87 ff 22 ff 2d ff c0 ff d8 ff c6 ff
0x00000670: d8 ff 8a ff d7 ff 19 ff 6d ff a6 ff f8 ff 45 ff
0x00000680: 27 ff c2 ff bf ff 56 ff af ff ce ff 2b ff 33 ff
0x00000690: 8e ff 4b ff 86 ff 35 ff b6 ff ca ff ef ff 21 ff
0x000006a0: b6 ff 76 ff 43 ff e4 ff 36 ff 1c ff aa ff 0e ff
0x000006b0: a6 ff 81 ff 28 ff 13 ff 28 ff 20 ff 59 ff 4f ff
0x000006c0: e2 ff 18 ff a6 ff 91 ff e6 ff d1 ff c4 ff 74 ff
0x000006d0: 1c ff 4a ff a9 ff d2 ff 15 ff 98 ff f3 ff cb ff
0x000006e0: 0f ff 37 ff af ff 45 ff 53 ff 5a ff 54 ff f9 ff
0x000006f0: db ff 7c ff 0c ff 03 ff 9c ff 65 ff 53 ff 7e ff
0x00000700: 7d ff f9 ff 0f ff 63 ff ca ff d3 ff d7 ff e6 ff
0x00000710: 1e ff 81 ff b9 ff 33 ff 19 ff ac ff fe ff 28 ff
0x00000720: e3 ff ae ff 6e ff 36 ff 08 ff c2 ff 2f ff e3 ff
0x00000730: 3e ff 3c ff e7 ff da ff a1 ff 3a ff 58 ff 1f ff
0x00000740: 33 ff 67 ff 82 ff fd ff 3a ff 5a ff e3 ff 58 ff
0x00000750: db ff 9c ff 8b ff f4 ff 49 ff 8a ff 1d ff 2c ff
0x00000760: 38 ff 8b ff 63 ff 40 ff 4d ff 92 ff 23 ff 8b ff
0x00000770: ce ff 0a ff 65 ff 70 ff 44 ff bd ff 8f ff 77 ff
0x00000780: 24 ff 11 ff 74 ff 5e ff 6b ff 58 ff b7 ff 46 ff
0x00000790: f4 ff 42 ff 3b ff 3d ff cc ff 58 ff 6a ff 04 ff
0x000007a0: e3 ff cd ff 44 ff 30 ff 5f ff 68 ff bb ff 2e ff
0x000007b0: 72 ff 20 ff 9e ff b7 ff dd ff 2d ff 2e ff 01 ff
0x000007c0: 3e ff a3 ff 5f ff aa ff fb ff 16 ff f0 ff ef ff
0x000007d0: 59 ff 2b ff 2d ff 25 ff 83 ff 97 ff 2a ff 66 ff
0x000007e0: 64 ff 6e ff 96 ff c3 ff d6 ff 51 ff f1 ff 49 ff
0x000007f0: 71 ff 8f ff 00 ff 4e ff bc ff 2e ff 4f ff fb ff
? OOB Data: d1 ff af ff a5 ff cc ff c5 ff 95 ff bc ff 1e ff
? OOB Data: c1 ff e9 ff 44 ff 44 ff 80 ff 6e ff ab ff e4 ff
? OOB Data: dc ff 41 ff a7 ff b3 ff 93 ff 99 ff fc ff 04 ff
? OOB Data: 28 ff fc ff 53 ff e5 ff 2a ff a2 ff e0 ff fc ff



Regards,
Minal
+91-80-2519-3129


From fengguang.wu at intel.com  Wed Oct  9 03:25:45 2013
From: fengguang.wu at intel.com (Fengguang Wu)
Date: Wed, 9 Oct 2013 15:25:45 +0800
Subject: [init_netsc520] WARNING: CPU: 0 PID: 1 at arch/x86/mm/ioremap.c:102
 __ioremap_caller()
Message-ID: <20131009072545.GA32231@localhost>

Greetings,

FYI, here is an old warning tat dates back at least to linux v3.0:

[    1.216507] NetSc520 flash device: 0x100000 at 0x200000
[    1.218335] ------------[ cut here ]------------
[    1.219996] WARNING: CPU: 0 PID: 1 at arch/x86/mm/ioremap.c:102 __ioremap_caller+0x13f/0x3f0()
[    1.223587] CPU: 0 PID: 1 Comm: swapper Not tainted 3.12.0-rc4-01587-g97d3ab9 #357
[    1.226402] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    1.228361]  00000000 00000000 cecd9e34 c0e00466 cecd9e64 c023c755 c1215818 00000000
[    1.232404]  00000001 c12147a0 00000066 c022f29f c022f29f 00000200 00000001 00000001
[    1.236439]  cecd9e74 c023c842 00000009 00000000 cecd9ec8 c022f29f 00000060 00000246
[    1.240473] Call Trace:
[    1.241633]  [<c0e00466>] dump_stack+0x16/0x18
[    1.243255]  [<c023c755>] warn_slowpath_common+0x75/0x90
[    1.245096]  [<c022f29f>] ? __ioremap_caller+0x13f/0x3f0
[    1.246915]  [<c022f29f>] ? __ioremap_caller+0x13f/0x3f0
[    1.248771]  [<c023c842>] warn_slowpath_null+0x22/0x30
[    1.250552]  [<c022f29f>] __ioremap_caller+0x13f/0x3f0
[    1.252361]  [<c0de99db>] ? printk+0x3d/0x3f
[    1.253936]  [<c15af4cd>] ? init_sc520cdp+0x216/0x216
[    1.255730]  [<c022f599>] ioremap_nocache+0x19/0x20
[    1.257456]  [<c15af511>] ? init_netsc520+0x44/0xf6
[    1.259217]  [<c15af511>] init_netsc520+0x44/0xf6
[    1.260891]  [<c156abc6>] do_one_initcall+0x108/0x1ce
[    1.262689]  [<c0713822>] ? strlen+0x12/0x20
[    1.264270]  [<c156a500>] ? repair_env_string+0x3/0x51
[    1.266085]  [<c0258646>] ? parse_args+0x296/0x4b0
[    1.267785]  [<c156adb4>] kernel_init_freeable+0x128/0x1ba
[    1.269653]  [<c156a4fd>] ? do_early_param+0x78/0x78
[    1.271413]  [<c0de4310>] kernel_init+0x10/0x140
[    1.273077]  [<c0e0c0db>] ret_from_kernel_thread+0x1b/0x30
[    1.274948]  [<c0de4300>] ? rest_init+0x70/0x70
[    1.276596] ---[ end trace e29a2c8115f76b14 ]---
[    1.279410] Creating 4 MTD partitions on "netsc520 Flash Bank":

git bisect  bad 97d3ab9b2207d72eb0f72347969c284562c374bd  # 21:47      0-     32  Merge branch 'perf/urgent'
git bisect  bad d0e639c9e06d44e713170031fe05fb60ebe680af  # 21:48      0-     80  Linux 3.12-rc4
git bisect  bad 6e4664525b1db28f8c4e1130957f70a94c19213e  # 21:53      0-      2  Linux 3.11
git bisect  bad 8bb495e3f02401ee6f76d1b1d77f3ac9f079e376  # 21:58      0-     11  Linux 3.10
git bisect  bad c1be5a5b1b355d40e6cf79cc979eb66dafa24ad1  # 22:03      0-      9  Linux 3.9
git bisect  bad 19f949f52599ba7c3f67a5897ac6be14bfcb1200  # 22:08      0-      1  Linux 3.8
git bisect  bad 29594404d7fe73cd80eaa4ee8c43dcc53970c60e  # 22:13      0-     10  Linux 3.7
git bisect  bad a0d271cbfed1dd50278c6b06bead3d00ba0a88f9  # 22:19      0-     12  Linux 3.6
git bisect  bad 28a33cbc24e4256c143dce96c7d93bf423229f92  # 22:23      0-      2  Linux 3.5
git bisect  bad 76e10d158efb6d4516018846f60c2ab5501900bc  # 22:28      0-     11  Linux 3.4
git bisect  bad c16fa4f2ad19908a47c63d8fa436a1178438c7e7  # 22:32      0-      3  Linux 3.3
git bisect  bad 805a6af8dba5dfdd35ec35dc52ec0122400b2610  # 22:37      0-      8  Linux 3.2
git bisect  bad c3b92c8787367a8bb53d57d9789b558f1295cc96  # 22:41      0-     13  Linux 3.1
git bisect  bad 02f8c6aee8df3cdc935e9bdd4f2d020306035dbe  # 22:45      0-     15  Linux 3.0
git bisect  bad 8b5ede69d24db939f52b47effff2f6fe1e83e08b  # 23:56      0-     32  powerpc/irq: Don't switch to irq stack from softirq stack
git bisect  bad a0cf1abc25ac197dd97b857c0f6341066a8cb1cf  # 23:56      0-     23  Add linux-next specific files for 20130927
git bisect  bad 97d3ab9b2207d72eb0f72347969c284562c374bd  # 23:56      0-     39  Merge branch 'perf/urgent'

Thanks,
Fengguang
-------------- next part --------------
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.12.0-rc4-01587-g97d3ab9 (kbuild at inn) (gcc version 4.8.1 (Debian 4.8.1-8) ) #357 Tue Oct 8 18:46:06 CST 2013
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[    0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000000fffdfff] usable
[    0.000000] BIOS-e820: [mem 0x000000000fffe000-0x000000000fffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000feffc000-0x00000000feffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
[    0.000000] debug: ignoring loglevel setting.
[    0.000000] Notice: NX (Execute Disable) protection cannot be enabled: non-PAE kernel!
[    0.000000] SMBIOS 2.4 present.
[    0.000000] DMI: Bochs Bochs, BIOS Bochs 01/01/2011
[    0.000000] Hypervisor detected: KVM
[    0.000000] e820: update [mem 0x00000000-0x00000fff] usable ==> reserved
[    0.000000] e820: remove [mem 0x000a0000-0x000fffff] usable
[    0.000000] e820: last_pfn = 0xfffe max_arch_pfn = 0x100000
[    0.000000] MTRR default type: write-back
[    0.000000] MTRR fixed ranges enabled:
[    0.000000]   00000-9FFFF write-back
[    0.000000]   A0000-BFFFF uncachable
[    0.000000]   C0000-FFFFF write-protect
[    0.000000] MTRR variable ranges enabled:
[    0.000000]   0 base 0080000000 mask FF80000000 uncachable
[    0.000000]   1 disabled
[    0.000000]   2 disabled
[    0.000000]   3 disabled
[    0.000000]   4 disabled
[    0.000000]   5 disabled
[    0.000000]   6 disabled
[    0.000000]   7 disabled
[    0.000000] x86 PAT enabled: cpu 0, old 0x70406, new 0x7010600070106
[    0.000000] Scanning 1 areas for low memory corruption
[    0.000000] initial memory mapped: [mem 0x00000000-0x01bfffff]
[    0.000000] Base memory trampoline at [c009b000] 9b000 size 16384
[    0.000000] init_memory_mapping: [mem 0x00000000-0x000fffff]
[    0.000000]  [mem 0x00000000-0x000fffff] page 4k
[    0.000000] init_memory_mapping: [mem 0x0f800000-0x0fbfffff]
[    0.000000]  [mem 0x0f800000-0x0fbfffff] page 2M
[    0.000000] init_memory_mapping: [mem 0x08000000-0x0f7fffff]
[    0.000000]  [mem 0x08000000-0x0f7fffff] page 2M
[    0.000000] init_memory_mapping: [mem 0x00100000-0x07ffffff]
[    0.000000]  [mem 0x00100000-0x003fffff] page 4k
[    0.000000]  [mem 0x00400000-0x07ffffff] page 2M
[    0.000000] init_memory_mapping: [mem 0x0fc00000-0x0fffdfff]
[    0.000000]  [mem 0x0fc00000-0x0fffdfff] page 4k
[    0.000000] BRK [0x01713000, 0x01713fff] PGTABLE
[    0.000000] log_buf_len: 8388608
[    0.000000] early log buf free: 128256(97%)
[    0.000000] RAMDISK: [mem 0x0fce4000-0x0ffeffff]
[    0.000000] ACPI: RSDP 000fd950 00014 (v00 BOCHS )
[    0.000000] ACPI: RSDT 0fffe450 00034 (v01 BOCHS  BXPCRSDT 00000001 BXPC 00000001)
[    0.000000] ACPI: FACP 0fffff80 00074 (v01 BOCHS  BXPCFACP 00000001 BXPC 00000001)
[    0.000000] ACPI: DSDT 0fffe490 011A9 (v01   BXPC   BXDSDT 00000001 INTL 20100528)
[    0.000000] ACPI: FACS 0fffff40 00040
[    0.000000] ACPI: SSDT 0ffff7a0 00796 (v01 BOCHS  BXPCSSDT 00000001 BXPC 00000001)
[    0.000000] ACPI: APIC 0ffff680 00080 (v01 BOCHS  BXPCAPIC 00000001 BXPC 00000001)
[    0.000000] ACPI: HPET 0ffff640 00038 (v01 BOCHS  BXPCHPET 00000001 BXPC 00000001)
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] mapped APIC to         ffffb000 (        fee00000)
[    0.000000] 0MB HIGHMEM available.
[    0.000000] 255MB LOWMEM available.
[    0.000000]   mapped low ram: 0 - 0fffe000
[    0.000000]   low ram: 0 - 0fffe000
[    0.000000] kvm-clock: Using msrs 4b564d01 and 4b564d00
[    0.000000] kvm-clock: cpu 0, msr 0:fffd001, boot clock
[    0.000000] BRK [0x01714000, 0x01714fff] PGTABLE
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x00001000-0x00ffffff]
[    0.000000]   Normal   [mem 0x01000000-0x0fffdfff]
[    0.000000]   HighMem  empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x00001000-0x0009efff]
[    0.000000]   node   0: [mem 0x00100000-0x0fffdfff]
[    0.000000] On node 0 totalpages: 65436
[    0.000000]   DMA zone: 32 pages used for memmap
[    0.000000]   DMA zone: 0 pages reserved
[    0.000000]   DMA zone: 3998 pages, LIFO batch:0
[    0.000000]   Normal zone: 480 pages used for memmap
[    0.000000]   Normal zone: 61438 pages, LIFO batch:15
[    0.000000] Using APIC driver default
[    0.000000] ACPI: PM-Timer IO Port: 0xb008
[    0.000000] ACPI: Local APIC address 0xfee00000
[    0.000000] mapped APIC to         ffffb000 (        fee00000)
[    0.000000] ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
[    0.000000] ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] enabled)
[    0.000000] ACPI: NR_CPUS/possible_cpus limit of 1 reached.  Processor 1/0x1 ignored.
[    0.000000] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[    0.000000] Using ACPI for processor (LAPIC) configuration information
[    0.000000] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[    0.000000] KVM setup async PF for cpu 0
[    0.000000] kvm-stealtime: cpu 0, msr 13c5d00
[    0.000000] PM: Registered nosave memory: [mem 0x0009f000-0x0009ffff]
[    0.000000] PM: Registered nosave memory: [mem 0x000a0000-0x000effff]
[    0.000000] PM: Registered nosave memory: [mem 0x000f0000-0x000fffff]
[    0.000000] e820: [mem 0x10000000-0xfeffbfff] available for PCI devices
[    0.000000] Booting paravirtualized kernel on KVM
[    0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 64924
[    0.000000] Kernel command line: hung_task_panic=1 rcutree.rcu_cpu_stall_timeout=100 log_buf_len=8M ignore_loglevel debug sched_debug apic=debug dynamic_printk sysrq_always_enabled panic=10  prompt_ramdisk=0 console=ttyS0,115200 console=tty0 vga=normal  root=/dev/ram0 rw link=/kernel-tests/run-queue/kvm/i386-randconfig-i009-1008/tip:master:97d3ab9b2207d72eb0f72347969c284562c374bd:bisect-usb/.vmlinuz-97d3ab9b2207d72eb0f72347969c284562c374bd-20131008185655-7-lkp-tt02 branch=tip/master BOOT_IMAGE=/kernel/i386-randconfig-i009-1008/97d3ab9b2207d72eb0f72347969c284562c374bd/vmlinuz-3.12.0-rc4-01587-g97d3ab9
[    0.000000] sysrq: sysrq always enabled.
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Initializing CPU#0
[    0.000000] Initializing HighMem for node 0 (00000000:00000000)
[    0.000000] Memory: 226400K/261744K available (12340K kernel code, 1761K rwdata, 5768K rodata, 940K init, 728K bss, 35344K reserved, 0K highmem)
[    0.000000] virtual kernel memory layout:
[    0.000000]     fixmap  : 0xfffe1000 - 0xfffff000   ( 120 kB)
[    0.000000]     pkmap   : 0xff800000 - 0xffc00000   (4096 kB)
[    0.000000]     vmalloc : 0xd07fe000 - 0xff7fe000   ( 752 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xcfffe000   ( 255 MB)
[    0.000000]       .init : 0xc156a000 - 0xc1655000   ( 940 kB)
[    0.000000]       .data : 0xc0e0d56f - 0xc15694b0   (7535 kB)
[    0.000000]       .text : 0xc0200000 - 0xc0e0d56f   (12341 kB)
[    0.000000] Checking if this processor honours the WP bit even in supervisor mode...Ok.
[    0.000000] SLUB: HWalign=128, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] CPU 0 irqstacks, hard=cec10000 soft=cec12000
[    0.000000] Console: colour VGA+ 80x25
[    0.000000] console [tty0] enabled
[    0.000000] console [ttyS0] enabled
[    0.000000] hpet clockevent registered
[    0.000000] tsc: Detected 2393.914 MHz processor
[    0.009999] Calibrating delay loop (skipped) preset value.. 4789.32 BogoMIPS (lpj=7979713)
[    0.010028] pid_max: default: 32768 minimum: 301
[    0.011986] Mount-cache hash table entries: 512
[    0.014314] Initializing cgroup subsys freezer
[    0.016696] Initializing cgroup subsys blkio
[    0.018386] Initializing cgroup subsys perf_event
[    0.020012] Initializing cgroup subsys net_prio
[    0.021828] mce: CPU supports 10 MCE banks
[    0.023428] Last level iTLB entries: 4KB 0, 2MB 0, 4MB 0
[    0.023428] Last level dTLB entries: 4KB 0, 2MB 0, 4MB 0
[    0.023428] tlb_flushall_shift: 6
[    0.026673] CPU: Intel Common KVM processor (fam: 0f, model: 06, stepping: 01)
[    0.053970] ACPI: Core revision 20130725
[    0.078123] ACPI: All ACPI Tables successfully acquired
[    0.080013] ACPI: setting ELCR to 0200 (from 0c00)
[    0.081778] ftrace: allocating 42611 entries in 84 pages
[    0.097072] Performance Events: unsupported Netburst CPU model 6 no PMU driver, software events only.
[    0.103769] ftrace: Allocated trace_printk buffers
[    0.115026] Getting VERSION: 50014
[    0.116496] Getting VERSION: 50014
[    0.116681] Getting ID: 0
[    0.117897] Getting ID: f000000
[    0.120019] Getting LVT0: 8700
[    0.121322] Getting LVT1: 8400
[    0.123400] enabled ExtINT on CPU#0
[    0.124854] Using local APIC timer interrupts.
[    0.124854] calibrating APIC timer ...
[    0.129999] ... lapic delta = 6249968
[    0.129999] ... PM-Timer delta = 357956
[    0.129999] ... PM-Timer result ok
[    0.129999] ..... delta 6249968
[    0.129999] ..... mult: 268434108
[    0.129999] ..... calibration result: 3333316
[    0.129999] ..... CPU clock speed is 2394.0492 MHz.
[    0.129999] ..... host bus clock speed is 1000.0316 MHz.
[    0.130513] devtmpfs: initialized
[    0.143045] regulator-dummy: no parameters
[    0.146810] NET: Registered protocol family 16
[    0.150981] cpuidle: using governor ladder
[    0.153134] ACPI: bus type PCI registered
[    0.153575] PCI: PCI BIOS revision 2.10 entry at 0xfc6d5, last bus=0
[    0.156669] PCI: Using configuration type 1 for base access
[    0.159166] Missing cpus node, bailing out
[    0.181509] bio: create slab <bio-0> at 0
[    0.184146] ACPI: Added _OSI(Module Device)
[    0.185726] ACPI: Added _OSI(Processor Device)
[    0.186670] ACPI: Added _OSI(3.0 _SCP Extensions)
[    0.188341] ACPI: Added _OSI(Processor Aggregator Device)
[    0.191064] ACPI: EC: Look up EC in DSDT
[    0.234947] ACPI: Interpreter enabled
[    0.236563] ACPI: (supports S0 S4 S5)
[    0.236670] ACPI: Using PIC for interrupt routing
[    0.238520] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    0.319093] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.320035] acpi PNP0A03:00: Unable to request _OSC control (_OSC support mask: 0x08)
[    0.328237] acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended PCI configuration space under this bridge.
[    0.330303] PCI host bridge to bus 0000:00
[    0.333345] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.335233] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7]
[    0.336676] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff]
[    0.338740] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff]
[    0.340010] pci_bus 0000:00: root bus resource [mem 0x80000000-0xfebfffff]
[    0.343413] pci 0000:00:00.0: [8086:1237] type 00 class 0x060000
[    0.348556] pci 0000:00:01.0: [8086:7000] type 00 class 0x060100
[    0.352313] pci 0000:00:01.1: [8086:7010] type 00 class 0x010180
[    0.357761] pci 0000:00:01.1: reg 0x20: [io  0xc060-0xc06f]
[    0.362567] pci 0000:00:01.3: [8086:7113] type 00 class 0x068000
[    0.363985] pci 0000:00:01.3: quirk: [io  0xb000-0xb03f] claimed by PIIX4 ACPI
[    0.366688] pci 0000:00:01.3: quirk: [io  0xb100-0xb10f] claimed by PIIX4 SMB
[    0.371782] pci 0000:00:02.0: [1013:00b8] type 00 class 0x030000
[    0.375402] pci 0000:00:02.0: reg 0x10: [mem 0xfc000000-0xfdffffff pref]
[    0.378014] pci 0000:00:02.0: reg 0x14: [mem 0xfebe0000-0xfebe0fff]
[    0.388560] pci 0000:00:02.0: reg 0x30: [mem 0xfebc0000-0xfebcffff pref]
[    0.391883] pci 0000:00:03.0: [1af4:1000] type 00 class 0x020000
[    0.394415] pci 0000:00:03.0: reg 0x10: [io  0xc040-0xc05f]
[    0.397671] pci 0000:00:03.0: reg 0x14: [mem 0xfebe1000-0xfebe1fff]
[    0.405824] pci 0000:00:03.0: reg 0x30: [mem 0xfebd0000-0xfebdffff pref]
[    0.408492] pci 0000:00:04.0: [8086:100e] type 00 class 0x020000
[    0.411066] pci 0000:00:04.0: reg 0x10: [mem 0xfeb80000-0xfeb9ffff]
[    0.414357] pci 0000:00:04.0: reg 0x14: [io  0xc000-0xc03f]
[    0.423023] pci 0000:00:04.0: reg 0x30: [mem 0xfeba0000-0xfebbffff pref]
[    0.426897] pci 0000:00:05.0: [8086:25ab] type 00 class 0x088000
[    0.429478] pci 0000:00:05.0: reg 0x10: [mem 0xfebe2000-0xfebe200f]
[    0.436912] pci_bus 0000:00: on NUMA node 0
[    0.443790] ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
[    0.448061] ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
[    0.452210] ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
[    0.456344] ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
[    0.458697] ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
[    0.466666] ACPI: Enabled 16 GPEs in block 00 to 0F
[    0.466684] ACPI: \_SB_.PCI0: notify handler is installed
[    0.470031] Found 1 acpi root devices
[    0.473815] vgaarb: device added: PCI:0000:00:02.0,decodes=io+mem,owns=io+mem,locks=none
[    0.476670] vgaarb: loaded
[    0.477859] vgaarb: bridge control possible 0000:00:02.0
[    0.481741] SCSI subsystem initialized
[    0.483311] libata version 3.00 loaded.
[    0.483473] ACPI: bus type USB registered
[    0.485133] usbcore: registered new interface driver usbfs
[    0.486737] usbcore: registered new interface driver hub
[    0.490133] usbcore: registered new device driver usb
[    0.492352] pps_core: LinuxPPS API ver. 1 registered
[    0.493336] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti at linux.it>
[    0.496724] PTP clock support registered
[    0.498883] Advanced Linux Sound Architecture Driver Initialized.
[    0.500003] PCI: Using ACPI for IRQ routing
[    0.503337] PCI: pci_cache_line_size set to 64 bytes
[    0.505277] e820: reserve RAM buffer [mem 0x0009fc00-0x0009ffff]
[    0.506678] e820: reserve RAM buffer [mem 0x0fffe000-0x0fffffff]
[    0.510179] NET: Registered protocol family 23
[    0.511916] Bluetooth: Core ver 2.16
[    0.513406] NET: Registered protocol family 31
[    0.515007] Bluetooth: HCI device and connection manager initialized
[    0.516682] Bluetooth: HCI socket layer initialized
[    0.518423] Bluetooth: L2CAP socket layer initialized
[    0.520033] Bluetooth: SCO socket layer initialized
[    0.521782] NET: Registered protocol family 8
[    0.523336] NET: Registered protocol family 20
[    0.525494] cfg80211: Calling CRDA to update world regulatory domain
[    0.527380] Switched to clocksource kvm-clock
[    0.529009] Warning: could not register annotated branches stats
[    0.627037] FS-Cache: Loaded
[    0.628627] CacheFiles: Loaded
[    0.630058] pnp: PnP ACPI init
[    0.631410] ACPI: bus type PNP registered
[    0.633316] pnp 00:00: Plug and Play ACPI device, IDs PNP0b00 (active)
[    0.635826] pnp 00:01: Plug and Play ACPI device, IDs PNP0303 (active)
[    0.638305] pnp 00:02: Plug and Play ACPI device, IDs PNP0f13 (active)
[    0.640863] pnp 00:03: [dma 2]
[    0.642352] pnp 00:03: Plug and Play ACPI device, IDs PNP0700 (active)
[    0.645106] pnp 00:04: Plug and Play ACPI device, IDs PNP0400 (active)
[    0.647834] pnp 00:05: Plug and Play ACPI device, IDs PNP0501 (active)
[    0.652293] pnp 00:06: Plug and Play ACPI device, IDs PNP0103 (active)
[    0.656226] pnp: PnP ACPI: found 7 devices
[    0.657765] ACPI: bus type PNP unregistered
[    0.706532] pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7]
[    0.708479] pci_bus 0000:00: resource 5 [io  0x0d00-0xffff]
[    0.710364] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff]
[    0.712428] pci_bus 0000:00: resource 7 [mem 0x80000000-0xfebfffff]
[    0.714551] NET: Registered protocol family 1
[    0.716200] pci 0000:00:00.0: Limiting direct PCI/PCI transfers
[    0.718200] pci 0000:00:01.0: PIIX3: Enabling Passive Release
[    0.720143] pci 0000:00:01.0: Activating ISA DMA hang workarounds
[    0.722222] pci 0000:00:02.0: Boot video device
[    0.723893] PCI: CLS 0 bytes, default 64
[    0.725718] Unpacking initramfs...
[    0.866597] Freeing initrd memory: 3120K (cfce4000 - cfff0000)
[    0.869630] Machine check injector initialized
[    0.871865] microcode: CPU0 sig=0xf61, pf=0x1, revision=0x1
[    0.873917] microcode: Microcode Update Driver: v2.00 <tigran at aivazian.fsnet.co.uk>, Peter Oruba
[    0.877031] Scanning for low memory corruption every 60 seconds
[    0.885878] HugeTLB registered 4 MB page size, pre-allocated 0 pages
[    0.914602] VFS: Disk quotas dquot_6.5.2
[    0.916502] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[    0.925754] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.933447] NTFS driver 2.1.30 [Flags: R/W DEBUG].
[    0.936952] EFS: 1.0a - http://aeschi.ch.eu.org/efs/
[    0.939020] jffs2: version 2.2. (NAND) 
[    0.945347] ROMFS MTD (C) 2007 Red Hat, Inc.
[    0.947677] QNX4 filesystem 0.2.3 registered.
[    0.949566] QNX6 filesystem 1.0.0 registered.
[    0.951176] fuse init (API version 7.22)
[    0.953910] SGI XFS with security attributes, large block/inode numbers, debug enabled
[    0.962694] BeFS version: 0.9.3
[    0.964323] OCFS2 1.5.0
[    0.966767] ocfs2: Registered cluster interface o2cb
[    0.968526] OCFS2 DLMFS 1.5.0
[    0.970146] OCFS2 User DLM kernel interface loaded
[    0.971852] OCFS2 Node Manager 1.5.0
[    0.974739] OCFS2 DLM 1.5.0
[    0.979882] GFS2 installed
[    0.981146] msgmni has been set to 448
[    0.991310] alg: No test for crc32 (crc32-table)
[    0.993277] alg: No test for lz4hc (lz4hc-generic)
[    0.995056] alg: No test for stdrng (krng)
[    1.001198] alg: No test for fips(ansi_cprng) (fips_ansi_cprng)
[    1.003347] NET: Registered protocol family 38
[    1.004984] Key type asymmetric registered
[    1.006514] Asymmetric key parser 'x509' registered
[    1.008600] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[    1.011395] io scheduler noop registered (default)
[    1.013090] test_string_helpers: Running tests...
[    1.016137] crc32: CRC_LE_BITS = 8, CRC_BE BITS = 8
[    1.017851] crc32: self tests passed, processed 225944 bytes in 665351 nsec
[    1.020668] crc32c: CRC_LE_BITS = 8
[    1.022092] crc32c: self tests passed, processed 225944 bytes in 303477 nsec
[    1.026255] usbcore: registered new interface driver udlfb
[    1.028187] usbcore: registered new interface driver smscufx
[    1.033287] uvesafb: VGABIOS Cirrus extension, VGABIOS Cirrus extension, 1.0, OEM: VGABIOS Cirrus extension, VBE v2.0
[    1.040267] uvesafb: no monitor limits have been set, default refresh rate will be used
[    1.043494] uvesafb: VBE state buffer size cannot be determined (eax=0x14f, err=0)
[    1.046406] uvesafb: scrolling: redraw
[    1.048105] VESA VGA: enable CONFIG_FB_LITTLE_ENDIAN to support this framebuffer
[    1.050817] uvesafb: failed to register framebuffer device
[    1.052861] uvesafb: probe of uvesafb.0 failed with error -22
[    1.055386] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
[    1.058143] ACPI: Power Button [PWRF]
[    1.061350] r3964: Philips r3964 Driver $Revision: 1.10 $
[    1.063196] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    1.089745] 00:05: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    1.123852] STMicroelectronics ASC driver initialized
[    1.126312] Non-volatile memory driver v1.3
[    1.130781] toshiba: not a supported Toshiba laptop
[    1.132762] platform pc8736x_gpio.0: NatSemi pc8736x GPIO Driver Initializing
[    1.135077] platform pc8736x_gpio.0: no device found
[    1.136891] nsc_gpio initializing
[    1.138297] telclk_interrupt = 0xf non-mcpbl0010 hw.
[    1.140085] smapi::smapi_init, ERROR invalid usSmapiID
[    1.141887] mwave: tp3780i::tp3780I_InitializeBoardData: Error: SMAPI is not available on this machine
[    1.145093] mwave: mwavedd::mwave_init: Error: Failed to initialize board data
[    1.147791] mwave: mwavedd::mwave_init: Error: Failed to initialize
[    1.150046] Hangcheck: starting hangcheck timer 0.9.1 (tick is 180 seconds, margin is 60 seconds).
[    1.153186] Hangcheck: Using getrawmonotonic().
[    1.154897] [drm] Initialized drm 1.1.0 20060810
[    1.156777] dummy-irq: no IRQ given.  Use irq=N
[    1.158507] lkdtm: No crash points registered, enable through debugfs
[    1.160810] Silicon Labs C2 port support v. 0.51.0 - (C) 2007 Rodolfo Giometti
[    1.163795] c2port c2port0: C2 port uc added
[    1.165403] c2port c2port0: uc flash has 30 blocks x 512 bytes (15360 bytes total)
[    1.169077] usbcore: registered new interface driver viperboard
[    1.171116] Uniform Multi-Platform E-IDE driver
[    1.172891] ide_generic: please use "probe_mask=0x3f" module parameter for probing all legacy ISA IDE ports
[    1.176227] ide-gd driver 1.18
[    1.177556] ide-cd driver 5.00
[    1.179295] Loading iSCSI transport class v2.0-870.
[    1.181655] hp_sw: device handler registered
[    1.183250] emc: device handler registered
[    1.184791] alua: device handler registered
[    1.186350] osst :I: Tape driver with OnStream support version 0.99.4
[    1.186350] osst :I: $Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $
[    1.190746] SCSI Media Changer driver v0.25 
[    1.194900] Rounding down aligned max_sectors from 4294967295 to 4294967288
[    1.200500] SSFDC read-only Flash Translation layer
[    1.202342] mtdoops: mtd device (mtddev=name/number) must be supplied
[    1.204457] L440GX flash mapping: failed to find PIIX4 ISA bridge, cannot continue
[    1.207300] platform physmap-flash.0: failed to claim resource 0
[    1.209517] Could not find PAR responsible for SC520CDP Flash Bank #1
[    1.211620] Trying default address 0x8c00000
[    1.213221] SC520 CDP flash device: 0x800000 at 0x8800000
[    1.215082] Failed to ioremap_nocache
[    1.216507] NetSc520 flash device: 0x100000 at 0x200000
[    1.218335] ------------[ cut here ]------------
[    1.219996] WARNING: CPU: 0 PID: 1 at arch/x86/mm/ioremap.c:102 __ioremap_caller+0x13f/0x3f0()
[    1.223587] CPU: 0 PID: 1 Comm: swapper Not tainted 3.12.0-rc4-01587-g97d3ab9 #357
[    1.226402] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
[    1.228361]  00000000 00000000 cecd9e34 c0e00466 cecd9e64 c023c755 c1215818 00000000
[    1.232404]  00000001 c12147a0 00000066 c022f29f c022f29f 00000200 00000001 00000001
[    1.236439]  cecd9e74 c023c842 00000009 00000000 cecd9ec8 c022f29f 00000060 00000246
[    1.240473] Call Trace:
[    1.241633]  [<c0e00466>] dump_stack+0x16/0x18
[    1.243255]  [<c023c755>] warn_slowpath_common+0x75/0x90
[    1.245096]  [<c022f29f>] ? __ioremap_caller+0x13f/0x3f0
[    1.246915]  [<c022f29f>] ? __ioremap_caller+0x13f/0x3f0
[    1.248771]  [<c023c842>] warn_slowpath_null+0x22/0x30
[    1.250552]  [<c022f29f>] __ioremap_caller+0x13f/0x3f0
[    1.252361]  [<c0de99db>] ? printk+0x3d/0x3f
[    1.253936]  [<c15af4cd>] ? init_sc520cdp+0x216/0x216
[    1.255730]  [<c022f599>] ioremap_nocache+0x19/0x20
[    1.257456]  [<c15af511>] ? init_netsc520+0x44/0xf6
[    1.259217]  [<c15af511>] init_netsc520+0x44/0xf6
[    1.260891]  [<c156abc6>] do_one_initcall+0x108/0x1ce
[    1.262689]  [<c0713822>] ? strlen+0x12/0x20
[    1.264270]  [<c156a500>] ? repair_env_string+0x3/0x51
[    1.266085]  [<c0258646>] ? parse_args+0x296/0x4b0
[    1.267785]  [<c156adb4>] kernel_init_freeable+0x128/0x1ba
[    1.269653]  [<c156a4fd>] ? do_early_param+0x78/0x78
[    1.271413]  [<c0de4310>] kernel_init+0x10/0x140
[    1.273077]  [<c0e0c0db>] ret_from_kernel_thread+0x1b/0x30
[    1.274948]  [<c0de4300>] ? rest_init+0x70/0x70
[    1.276596] ---[ end trace e29a2c8115f76b14 ]---
[    1.279410] Creating 4 MTD partitions on "netsc520 Flash Bank":
[    1.281430] 0x000000000000-0x0000000c0000 : "NetSc520 boot kernel"
[    1.284618] 0x0000000c0000-0x000000100000 : "NetSc520 Low BIOS"
[    1.287569] 0x000000100000-0x000000f80000 : "NetSc520 file system"
[    1.289651] mtd: partition "NetSc520 file system" is out of reach -- disabled
[    1.292884] 0x000000f80000-0x000001000000 : "NetSc520 High BIOS"
[    1.294898] mtd: partition "NetSc520 High BIOS" is out of reach -- disabled
[    1.298092] Generic platform RAM MTD, (c) 2004 Simtec Electronics
[    1.300226] slram: not enough parameters.
[    1.307768] HSI/SSI char device loaded
[    1.309353] ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393 at maroon.tc.umn.edu>
[    1.312591] ipddp0: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393 at maroon.tc.umn.edu>
[    1.315684] vcan: Virtual CAN interface driver
[    1.317303] CAN device driver interface
[    1.318853] usbcore: registered new interface driver ems_usb
[    1.320807] usbcore: registered new interface driver kvaser_usb
[    1.322915] sja1000 CAN netdevice driver
[    1.324543] usbcore: registered new interface driver irda-usb
[    1.326524] usbcore: registered new interface driver stir4200
[    1.330167] usbcore: registered new interface driver ks959-sir
[    1.332524] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.334680] ehci-pci: EHCI PCI platform driver
[    1.336447] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[    1.338543] ohci-pci: OHCI PCI platform driver
[    1.340225] ohci-platform: OHCI generic platform driver
[    1.344239] fusbh200_hcd: FUSBH200 Host Controller (EHCI) Driver
[    1.346378] Warning! fusbh200_hcd should always be loaded before uhci_hcd and ohci_hcd, not after
[    1.349556] fotg210_hcd: FOTG210 Host Controller (EHCI) Driver
[    1.351514] 
[    1.354810] usbcore: registered new interface driver cdc_acm
[    1.356714] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[    1.359670] usbcore: registered new interface driver usblp
[    1.361603] usbcore: registered new interface driver cdc_wdm
[    1.363607] usbcore: registered new interface driver usb-storage
[    1.365686] usbcore: registered new interface driver ums-alauda
[    1.367718] usbcore: registered new interface driver ums-cypress
[    1.369749] usbcore: registered new interface driver ums_eneub6250
[    1.371846] usbcore: registered new interface driver ums-freecom
[    1.373879] usbcore: registered new interface driver ums-isd200
[    1.375924] usbcore: registered new interface driver ums-jumpshot
[    1.377990] usbcore: registered new interface driver ums-realtek
[    1.380058] usbcore: registered new interface driver ums-sddr09
[    1.382093] usbcore: registered new interface driver ums-sddr55
[    1.384101] usbcore: registered new interface driver ums-usbat
[    1.386161] usbcore: registered new interface driver mdc800
[    1.388062] mdc800: v0.7.5 (30/10/2000):USB Driver for Mustek MDC800 Digital Camera
[    1.390917] usbcore: registered new interface driver microtekX6
[    1.392978] usbcore: registered new interface driver adutux
[    1.395052] usbcore: registered new interface driver appledisplay
[    1.397114] usbcore: registered new interface driver cytherm
[    1.399100] usbcore: registered new interface driver emi26 - firmware loader
[    1.401397] usbcore: registered new interface driver emi62 - firmware loader
[    1.403677] usbcore: registered new interface driver iowarrior
[    1.405697] usbcore: registered new interface driver isight_firmware
[    1.407849] usbcore: registered new interface driver usblcd
[    1.409784] usbcore: registered new interface driver usbtest
[    1.411746] usbcore: registered new interface driver usbsevseg
[    1.413740] usbcore: registered new interface driver yurex
[    1.416741] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
[    1.420806] serio: i8042 KBD port at 0x60,0x64 irq 1
[    1.422601] serio: i8042 AUX port at 0x60,0x64 irq 12
[    1.526801] mousedev: PS/2 mouse device common for all mice
[    1.528927] evbug: Connected device: input0 (Power Button at LNXPWRBN/button/input0)
[    1.533353] usbcore: registered new interface driver xpad
[    1.535339] usbcore: registered new interface driver usb_acecad
[    1.537367] usbcore: registered new interface driver aiptek
[    1.539342] usbcore: registered new interface driver gtco
[    1.541264] usbcore: registered new interface driver hanwang
[    1.543231] usbcore: registered new interface driver kbtab
[    1.545167] usbcore: registered new interface driver wacom
[    1.547992] usbcore: registered new interface driver usbtouchscreen
[    1.550697] usbcore: registered new interface driver ati_remote2
[    1.552763] cm109: Keymap for Komunikate KIP1000 phone loaded
[    1.554758] usbcore: registered new interface driver cm109
[    1.556626] cm109: CM109 phone driver: 20080805 (C) Alfred E. Heggestad
[    1.558975] usbcore: registered new interface driver keyspan_remote
[    1.561486] input: PC Speaker as /devices/platform/pcspkr/input/input1
[    1.564443] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input2
[    1.567665] evbug: Connected device: input1 (PC Speaker at isa0061/input0)
[    1.569967] wistron_btns: System unknown
[    1.571545] usbcore: registered new interface driver yealink
[    1.573690] usbcore: registered new interface driver i2c-diolan-u2c
[    1.576041] pps pps0: new PPS source ktimer
[    1.577596] pps pps0: ktimer PPS source registered
[    1.579329] pps_ldisc: PPS line discipline registered
[    1.581158] Driver for 1-wire Dallas network protocol.
[    1.583200] 1-Wire driver for the DS2760 battery monitor  chip  - (c) 2004-2005, Szabolcs Gyurko
[    1.592084] intel_powerclamp: Intel powerclamp does not run on family 15 model 6
[    1.594895] usbcore: registered new interface driver pcwd_usb
[    1.599808] acquirewdt: WDT driver for Acquire single board computer initialising
[    1.602806] acquirewdt: I/O address 0x0043 already in use
[    1.604692] acquirewdt: probe of acquirewdt failed with error -5
[    1.606674] advantechwdt: WDT driver for Advantech single board computer initialising
[    1.610013] evbug: Connected device: input2 (AT Translated Set 2 keyboard at isa0060/serio0/input0)
[    1.613797] advantechwdt: initialized. timeout=60 sec (nowayout=1)
[    1.615956] wafer5823wdt: WDT driver for Wafer 5823 single board computer initialising
[    1.618847] wafer5823wdt: I/O address 0x0443 already in use
[    1.620868] it87_wdt: no device
[    1.622257] pc87413_wdt: Version 1.1 at io 0x2E
[    1.623890] pc87413_wdt: cannot register miscdev on minor=130 (err=-16)
[    1.626077] sbc60xxwdt: I/O address 0x0443 already in use
[    1.627936] sbc8360: failed to register misc device
[    1.629685] cpu5wdt: misc_register failed
[    1.631309] w83697hf_wdt: WDT driver for W83697HF/HG initializing
[    1.633351] w83697hf_wdt: watchdog not found at address 0x2e
[    1.635279] w83697hf_wdt: No W83697HF/HG could be found
[    1.637095] w83697ug_wdt: WDT driver for the Winbond(TM) W83697UG/UF Super I/O chip initialising
[    1.640237] w83697ug_wdt: No W83697UG/UF could be found
[    1.642069] w83977f_wdt: driver v1.00
[    1.643503] w83977f_wdt: cannot register miscdev on minor=130 (err=-16)
[    1.645662] machzwd: MachZ ZF-Logic Watchdog driver initializing
[    1.647673] machzwd: no ZF-Logic found
[    1.649212] watchdog: Software Watchdog: cannot register miscdev on minor=130 (err=-16).
[    1.652137] watchdog: Software Watchdog: a legacy watchdog module is probably present.
[    1.657713] softdog: Software Watchdog Timer: 0.08 initialized. soft_noboot=0 soft_margin=60 sec soft_panic=0 (nowayout=1)
[    1.663226] device-mapper: ioctl: 4.26.0-ioctl (2013-08-15) initialised: dm-devel at redhat.com
[    1.667181] device-mapper: dm-log-userspace: version 1.1.0 loaded
[    1.669280] usbcore: registered new interface driver bpa10x
[    1.671336] usbcore: registered new interface driver btusb
[    1.673276] usbcore: registered new interface driver ath3k
[    1.675215] lguest: switcher text too large (4384)
[    1.676964] sdhci: Secure Digital Host Controller Interface driver
[    1.679027] sdhci: Copyright(c) Pierre Ossman
[    1.680617] wbsd: Winbond W83L51xD SD/MMC card interface driver
[    1.682612] wbsd: Copyright(c) Pierre Ossman
[    1.684313] usbcore: registered new interface driver ushc
[    1.687132] ledtrig-cpu: registered to indicate activity on CPUs
[    1.690078] dcdbas dcdbas: Dell Systems Management Base Driver (version 5.6.0-3.2)
[    1.695925] Audio Excel DSP 16 init driver Copyright (C) Riccardo Facchetti 1995-98
[    1.698765] aedsp16: I/O, IRQ and DMA are mandatory
[    1.700507] pss: mss_io, mss_dma, mss_irq and pss_io must be set.
[    1.702551] ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996
[    1.705374] ad1848: No ISAPnP cards found, trying standard ones...
[    1.707425] MediaTrix audio driver Copyright (C) by Hannu Savolainen 1993-1996
[    1.710178] I/O, IRQ, DMA and type are mandatory
[    1.711846] sb: Init: Starting Probe...
[    1.713384] sb: Init: Done
[    1.714653] Cyrix Kahlua VSA1 XpressAudio support (c) Copyright 2003 Red Hat Inc
[    1.719436] Error: Driver 'da9055' is already registered, aborting...
[    1.726908] NET: Registered protocol family 26
[    1.728584] NET: Registered protocol family 17
[    1.730280] NET: Registered protocol family 15
[    1.732232] Ebtables v2.0 registered
[    1.733760] NET: Registered protocol family 5
[    1.735479] NET: Registered protocol family 9
[    1.737096] X.25 for Linux Version 0.2
[    1.738627] can: controller area network core (rev 20120528 abi 9)
[    1.741078] NET: Registered protocol family 29
[    1.742695] can: raw protocol (rev 20120528)
[    1.744281] can: netlink gateway (rev 20130117) max_hops=1
[    1.747120] Bluetooth: RFCOMM TTY layer initialized
[    1.748895] Bluetooth: RFCOMM socket layer initialized
[    1.750701] Bluetooth: RFCOMM ver 1.11
[    1.752190] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[    1.754027] Bluetooth: BNEP filters: protocol multicast
[    1.755868] Bluetooth: BNEP socket layer initialized
[    1.757623] Bluetooth: HIDP (Human Interface Emulation) ver 1.2
[    1.759646] Bluetooth: HIDP socket layer initialized
[    1.761429] lec:lane_module_init: lec.c: initialized
[    1.763184] NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team
[    1.766787] DECnet: Routing cache hash table of 1024 buckets, 4Kbytes
[    1.769232] NET: Registered protocol family 12
[    1.770915] NET: Registered protocol family 35
[    1.773186] 8021q: 802.1Q VLAN Support v1.8
[    1.774799] 9pnet: Installing 9P2000 support
[    1.776453] NET: Registered protocol family 37
[    1.778338] batman_adv: B.A.T.M.A.N. advanced 2013.4.0 (compatibility version 14) loaded
[    1.781274] openvswitch: Open vSwitch switching datapath
[    1.783587] mpls_gso: MPLS GSO support
[    1.786157] Using IPI Shortcut mode
[    1.787963] PM: Hibernation image not present or could not be loaded.
[    1.791038] Key type encrypted registered
[    1.794262] BIOS EDD facility v0.16 2004-Jun-25, 0 devices found
[    1.796305] EDD information not available.
[    1.798050] ### dt-test ### No testcase data in device tree; not running tests
[    1.800759] ALSA device list:
[    1.802066]   No soundcards found.
[    1.804146] Freeing unused kernel memory: 940K (c156a000 - c1655000)
[    1.806781] Write protecting the kernel text: 12344k
[    1.808837] Write protecting the kernel read-only data: 5772k
[    1.891197] tsc: Refined TSC clocksource calibration: 2393.911 MHz
[    1.915861] udev[128]: starting version 164
[    2.640527] GFS2: path_lookup on rootfs returned error -2
Kernel tests: Boot OK!
[    3.406734] trinity uses obsolete (PF_INET,SOCK_PACKET)
[    6.136554] Bits 55-60 of /proc/PID/pagemap entries are about to stop being page-shift some time soon. See the linux/Documentation/vm/pagemap.txt for details.
[   48.819765] VFS: Warning: trinity-child0 using old stat() call. Recompile your binary.
[   48.825376] VFS: Warning: trinity-child0 using old stat() call. Recompile your binary.
[   48.828422] VFS: Warning: trinity-child0 using old stat() call. Recompile your binary.
[   48.832110] VFS: Warning: trinity-child0 using old stat() call. Recompile your binary.
[   54.845101] VFS: Warning: trinity-child0 using old stat() call. Recompile your binary.
[   71.740195] Unregister pv shared memory for cpu 0
[   71.742083] no ifx modem active;
[   71.743773] reboot: Restarting system
[   71.745322] reboot: machine restart
Elapsed time: 80
qemu-system-x86_64 -cpu kvm64 -enable-kvm -kernel /kernel/i386-randconfig-i009-1008/97d3ab9b2207d72eb0f72347969c284562c374bd/vmlinuz-3.12.0-rc4-01587-g97d3ab9 -append 'hung_task_panic=1 rcutree.rcu_cpu_stall_timeout=100 log_buf_len=8M ignore_loglevel debug sched_debug apic=debug dynamic_printk sysrq_always_enabled panic=10  prompt_ramdisk=0 console=ttyS0,115200 console=tty0 vga=normal  root=/dev/ram0 rw link=/kernel-tests/run-queue/kvm/i386-randconfig-i009-1008/tip:master:97d3ab9b2207d72eb0f72347969c284562c374bd:bisect-usb/.vmlinuz-97d3ab9b2207d72eb0f72347969c284562c374bd-20131008185655-7-lkp-tt02 branch=tip/master BOOT_IMAGE=/kernel/i386-randconfig-i009-1008/97d3ab9b2207d72eb0f72347969c284562c374bd/vmlinuz-3.12.0-rc4-01587-g97d3ab9'  -initrd /kernel-tests/initrd/yocto-minimal-i386.cgz -m 256M -smp 2 -net nic,vlan=0,macaddr=00:00:00:00:00:00,model=virtio -net user,vlan=0,hostfwd=tcp::5365-:22 -net nic,vlan=1,model=e1000 -net user,vlan=1 -boot order=nc -no-reboot -watchdog i6300esb -pidfile /dev/shm/kboot/pid-yocto-lkp-tt02-20 -serial file:/dev/shm/kboot/serial-yocto-lkp-tt02-20 -daemonize -display none -monitor null 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bisect-97d3ab9b2207d72eb0f72347969c284562c374bd-i386-randconfig-i009-1008-arch-x---mm-ioremap-c-7748.log
Type: application/octet-stream
Size: 91991 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/03b4fd32/attachment-0001.obj>
-------------- next part --------------
#
# Automatically generated file; DO NOT EDIT.
# Linux/i386 3.12.0-rc4 Kernel Configuration
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
CONFIG_X86=y
CONFIG_INSTRUCTION_DECODER=y
CONFIG_OUTPUT_FORMAT="elf32-i386"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_NEED_SG_DMA_LENGTH=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_HAS_CPU_RELAX=y
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_CPU_AUTOPROBE=y
CONFIG_HAVE_SETUP_PER_CPU_AREA=y
CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y
CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
# CONFIG_ZONE_DMA32 is not set
# CONFIG_AUDIT_ARCH is not set
CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-ecx -fcall-saved-edx"
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
CONFIG_CONSTRUCTORS=y
CONFIG_IRQ_WORK=y
CONFIG_BUILDTIME_EXTABLE_SORT=y

#
# General setup
#
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_COMPILE_TEST=y
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_BZIP2=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_LZ4=y
# CONFIG_KERNEL_GZIP is not set
# CONFIG_KERNEL_BZIP2 is not set
# CONFIG_KERNEL_LZMA is not set
CONFIG_KERNEL_XZ=y
# CONFIG_KERNEL_LZO is not set
# CONFIG_KERNEL_LZ4 is not set
CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
CONFIG_FHANDLE=y
# CONFIG_AUDIT is not set

#
# IRQ subsystem
#
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_IRQ_DOMAIN=y
# CONFIG_IRQ_DOMAIN_DEBUG is not set
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_SPARSE_IRQ=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_KTIME_SCALAR=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
CONFIG_GENERIC_CMOS_UPDATE=y

#
# Timers subsystem
#
CONFIG_HZ_PERIODIC=y
# CONFIG_NO_HZ_IDLE is not set
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set

#
# CPU/Task time and stats accounting
#
# CONFIG_TICK_CPU_ACCOUNTING is not set
CONFIG_IRQ_TIME_ACCOUNTING=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set

#
# RCU Subsystem
#
CONFIG_TINY_RCU=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_RCU_STALL_COMMON is not set
# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
# CONFIG_IKCONFIG_PROC is not set
CONFIG_LOG_BUF_SHIFT=17
CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
CONFIG_ARCH_WANTS_PROT_NUMA_PROT_NONE=y
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
# CONFIG_CGROUP_DEVICE is not set
CONFIG_CPUSETS=y
# CONFIG_PROC_PID_CPUSET is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_RESOURCE_COUNTERS is not set
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_CFS_BANDWIDTH is not set
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_BLK_CGROUP=y
CONFIG_DEBUG_BLK_CGROUP=y
# CONFIG_CHECKPOINT_RESTORE is not set
CONFIG_NAMESPACES=y
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
CONFIG_USER_NS=y
# CONFIG_PID_NS is not set
CONFIG_NET_NS=y
CONFIG_UIDGID_STRICT_TYPE_CHECKS=y
CONFIG_SCHED_AUTOGROUP=y
# CONFIG_SYSFS_DEPRECATED is not set
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_RD_GZIP=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_RD_XZ=y
CONFIG_RD_LZO=y
CONFIG_RD_LZ4=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_HAVE_UID16=y
CONFIG_SYSCTL_EXCEPTION_TRACE=y
CONFIG_HAVE_PCSPKR_PLATFORM=y
# CONFIG_EXPERT is not set
CONFIG_UID16=y
# CONFIG_SYSCTL_SYSCALL is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_PCSPKR_PLATFORM=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_PCI_QUIRKS=y
# CONFIG_EMBEDDED is not set
CONFIG_HAVE_PERF_EVENTS=y

#
# Kernel Performance Events And Counters
#
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_PROFILING is not set
CONFIG_TRACEPOINTS=y
CONFIG_HAVE_OPROFILE=y
CONFIG_OPROFILE_NMI_TIMER=y
# CONFIG_JUMP_LABEL is not set
CONFIG_UPROBES=y
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_HAVE_IOREMAP_PROT=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
CONFIG_HAVE_OPTPROBES=y
CONFIG_HAVE_KPROBES_ON_FTRACE=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
CONFIG_HAVE_CMPXCHG_LOCAL=y
CONFIG_HAVE_CMPXCHG_DOUBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y

#
# GCOV-based kernel profiling
#
CONFIG_GCOV_KERNEL=y
# CONFIG_GCOV_PROFILE_ALL is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
# CONFIG_MODULES is not set
CONFIG_BLOCK=y
CONFIG_LBDAF=y
CONFIG_BLK_DEV_BSG=y
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_THROTTLING=y
# CONFIG_BLK_CMDLINE_PARSER is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_ACORN_PARTITION is not set
# CONFIG_AIX_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
CONFIG_AMIGA_PARTITION=y
CONFIG_ATARI_PARTITION=y
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_BSD_DISKLABEL is not set
CONFIG_MINIX_SUBPARTITION=y
# CONFIG_SOLARIS_X86_PARTITION is not set
CONFIG_UNIXWARE_DISKLABEL=y
# CONFIG_LDM_PARTITION is not set
CONFIG_SGI_PARTITION=y
CONFIG_ULTRIX_PARTITION=y
CONFIG_SUN_PARTITION=y
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
CONFIG_SYSV68_PARTITION=y
# CONFIG_CMDLINE_PARTITION is not set

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
CONFIG_ASN1=y
CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
CONFIG_INLINE_READ_UNLOCK=y
CONFIG_INLINE_READ_UNLOCK_IRQ=y
CONFIG_INLINE_WRITE_UNLOCK=y
CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
CONFIG_FREEZER=y

#
# Processor type and features
#
CONFIG_ZONE_DMA=y
# CONFIG_SMP is not set
# CONFIG_X86_MPPARSE is not set
CONFIG_X86_EXTENDED_PLATFORM=y
# CONFIG_X86_GOLDFISH is not set
# CONFIG_X86_WANT_INTEL_MID is not set
# CONFIG_X86_INTEL_LPSS is not set
CONFIG_X86_RDC321X=y
# CONFIG_X86_32_IRIS is not set
# CONFIG_SCHED_OMIT_FRAME_POINTER is not set
# CONFIG_KVMTOOL_TEST_ENABLE is not set
CONFIG_HYPERVISOR_GUEST=y
CONFIG_PARAVIRT=y
# CONFIG_PARAVIRT_DEBUG is not set
# CONFIG_XEN_PRIVILEGED_GUEST is not set
CONFIG_KVM_GUEST=y
# CONFIG_KVM_DEBUG_FS is not set
# CONFIG_LGUEST_GUEST is not set
# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
CONFIG_PARAVIRT_CLOCK=y
CONFIG_NO_BOOTMEM=y
# CONFIG_MEMTEST is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MELAN is not set
CONFIG_MGEODEGX1=y
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_MVIAC7 is not set
# CONFIG_MCORE2 is not set
# CONFIG_MATOM is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_INTERNODE_CACHE_SHIFT=4
CONFIG_X86_L1_CACHE_SHIFT=4
# CONFIG_X86_PPRO_FENCE is not set
CONFIG_X86_ALIGNMENT_16=y
CONFIG_X86_TSC=y
CONFIG_X86_MINIMUM_CPU_FAMILY=4
CONFIG_X86_DEBUGCTLMSR=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_TRANSMETA_32=y
CONFIG_HPET_TIMER=y
CONFIG_DMI=y
CONFIG_NR_CPUS=1
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_COUNT=y
CONFIG_X86_UP_APIC=y
# CONFIG_X86_UP_IOAPIC is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_INTEL is not set
# CONFIG_X86_MCE_AMD is not set
CONFIG_X86_ANCIENT_MCE=y
CONFIG_X86_MCE_INJECT=y
CONFIG_VM86=y
CONFIG_TOSHIBA=y
# CONFIG_I8K is not set
CONFIG_X86_REBOOTFIXUPS=y
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
# CONFIG_MICROCODE_AMD is not set
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_MICROCODE_INTEL_LIB=y
CONFIG_MICROCODE_INTEL_EARLY=y
# CONFIG_MICROCODE_AMD_EARLY is not set
CONFIG_MICROCODE_EARLY=y
# CONFIG_X86_MSR is not set
CONFIG_X86_CPUID=y
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_HIGHMEM=y
CONFIG_NEED_NODE_MEMMAP_SIZE=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ILLEGAL_POINTER_VALUE=0
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTPLUG_SPARSE=y
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_COMPACTION is not set
# CONFIG_MIGRATION is not set
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
# CONFIG_BOUNCE is not set
CONFIG_NEED_BOUNCE_POOL=y
CONFIG_VIRT_TO_BUS=y
# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
# CONFIG_TRANSPARENT_HUGEPAGE is not set
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_CLEANCACHE=y
# CONFIG_FRONTSWAP is not set
# CONFIG_CMA is not set
# CONFIG_ZBUD is not set
CONFIG_HIGHPTE=y
CONFIG_X86_CHECK_BIOS_CORRUPTION=y
CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y
CONFIG_X86_RESERVE_LOW=64
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_ARCH_USES_PG_UNCACHED=y
CONFIG_ARCH_RANDOM=y
CONFIG_X86_SMAP=y
# CONFIG_EFI is not set
# CONFIG_SECCOMP is not set
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_300=y
# CONFIG_HZ_1000 is not set
CONFIG_HZ=300
# CONFIG_SCHED_HRTICK is not set
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x1000000
CONFIG_RELOCATABLE=y
CONFIG_X86_NEED_RELOCS=y
CONFIG_PHYSICAL_ALIGN=0x200000
# CONFIG_COMPAT_VDSO is not set
# CONFIG_CMDLINE_BOOL is not set
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y

#
# Power management and ACPI options
#
# CONFIG_SUSPEND is not set
CONFIG_HIBERNATE_CALLBACKS=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""
CONFIG_PM_SLEEP=y
# CONFIG_PM_AUTOSLEEP is not set
CONFIG_PM_WAKELOCKS=y
CONFIG_PM_WAKELOCKS_LIMIT=100
CONFIG_PM_WAKELOCKS_GC=y
CONFIG_PM_RUNTIME=y
CONFIG_PM=y
CONFIG_PM_DEBUG=y
# CONFIG_PM_ADVANCED_DEBUG is not set
CONFIG_PM_SLEEP_DEBUG=y
# CONFIG_PM_TRACE_RTC is not set
CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
CONFIG_ACPI=y
CONFIG_ACPI_SLEEP=y
# CONFIG_ACPI_PROCFS is not set
# CONFIG_ACPI_PROCFS_POWER is not set
# CONFIG_ACPI_EC_DEBUGFS is not set
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
# CONFIG_ACPI_VIDEO is not set
CONFIG_ACPI_FAN=y
# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=y
# CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_CUSTOM_DSDT_FILE=""
# CONFIG_ACPI_CUSTOM_DSDT is not set
# CONFIG_ACPI_INITRD_TABLE_OVERRIDE is not set
CONFIG_ACPI_BLACKLIST_YEAR=0
# CONFIG_ACPI_DEBUG is not set
# CONFIG_ACPI_PCI_SLOT is not set
CONFIG_X86_PM_TIMER=y
# CONFIG_ACPI_CONTAINER is not set
# CONFIG_ACPI_HOTPLUG_MEMORY is not set
# CONFIG_ACPI_SBS is not set
# CONFIG_ACPI_HED is not set
# CONFIG_ACPI_CUSTOM_METHOD is not set
# CONFIG_ACPI_APEI is not set
CONFIG_SFI=y
# CONFIG_APM is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# CPU Idle
#
CONFIG_CPU_IDLE=y
CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
CONFIG_CPU_IDLE_GOV_LADDER=y
# CONFIG_CPU_IDLE_GOV_MENU is not set
# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
# CONFIG_INTEL_IDLE is not set

#
# Bus options (PCI etc.)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
# CONFIG_PCI_GOOLPC is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_OLPC=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCIEPORTBUS is not set
# CONFIG_PCI_MSI is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCI_PRI is not set
# CONFIG_PCI_PASID is not set
# CONFIG_PCI_IOAPIC is not set
CONFIG_PCI_LABEL=y

#
# PCI host controller drivers
#
CONFIG_ISA_DMA_API=y
# CONFIG_ISA is not set
# CONFIG_SCx200 is not set
CONFIG_OLPC=y
# CONFIG_OLPC_XO15_SCI is not set
CONFIG_ALIX=y
# CONFIG_NET5501 is not set
CONFIG_GEOS=y
CONFIG_AMD_NB=y
CONFIG_PCCARD=y
CONFIG_PCMCIA=y
# CONFIG_PCMCIA_LOAD_CIS is not set
CONFIG_CARDBUS=y

#
# PC-card bridges
#
# CONFIG_YENTA is not set
# CONFIG_PD6729 is not set
# CONFIG_I82092 is not set
# CONFIG_HOTPLUG_PCI is not set
# CONFIG_RAPIDIO is not set
CONFIG_X86_SYSFB=y

#
# Executable file formats / Emulations
#
CONFIG_BINFMT_ELF=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_BINFMT_SCRIPT=y
CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=y
CONFIG_COREDUMP=y
CONFIG_HAVE_ATOMIC_IOMAP=y
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
CONFIG_UNIX_DIAG=y
CONFIG_XFRM=y
CONFIG_XFRM_ALGO=y
CONFIG_XFRM_SUB_POLICY=y
CONFIG_XFRM_MIGRATE=y
CONFIG_NET_KEY=y
CONFIG_NET_KEY_MIGRATE=y
# CONFIG_INET is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_NETFILTER_ADVANCED=y
CONFIG_NETFILTER_XTABLES=y

#
# DECnet: Netfilter Configuration
#
CONFIG_DECNET_NF_GRABULATOR=y
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
# CONFIG_BRIDGE_EBT_T_FILTER is not set
CONFIG_BRIDGE_EBT_T_NAT=y
# CONFIG_BRIDGE_EBT_802_3 is not set
CONFIG_BRIDGE_EBT_AMONG=y
CONFIG_BRIDGE_EBT_ARP=y
CONFIG_BRIDGE_EBT_IP=y
CONFIG_BRIDGE_EBT_LIMIT=y
# CONFIG_BRIDGE_EBT_MARK is not set
# CONFIG_BRIDGE_EBT_PKTTYPE is not set
CONFIG_BRIDGE_EBT_STP=y
# CONFIG_BRIDGE_EBT_VLAN is not set
# CONFIG_BRIDGE_EBT_DNAT is not set
# CONFIG_BRIDGE_EBT_MARK_T is not set
# CONFIG_BRIDGE_EBT_REDIRECT is not set
CONFIG_BRIDGE_EBT_SNAT=y
CONFIG_BRIDGE_EBT_LOG=y
CONFIG_BRIDGE_EBT_ULOG=y
# CONFIG_BRIDGE_EBT_NFLOG is not set
CONFIG_ATM=y
CONFIG_ATM_LANE=y
CONFIG_STP=y
CONFIG_MRP=y
CONFIG_BRIDGE=y
# CONFIG_BRIDGE_VLAN_FILTERING is not set
CONFIG_VLAN_8021Q=y
# CONFIG_VLAN_8021Q_GVRP is not set
CONFIG_VLAN_8021Q_MVRP=y
CONFIG_DECNET=y
CONFIG_DECNET_ROUTER=y
CONFIG_LLC=y
CONFIG_LLC2=y
# CONFIG_IPX is not set
CONFIG_ATALK=y
CONFIG_DEV_APPLETALK=y
CONFIG_IPDDP=y
CONFIG_IPDDP_ENCAP=y
CONFIG_X25=y
CONFIG_LAPB=y
CONFIG_PHONET=y
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
CONFIG_DCB=y
# CONFIG_DNS_RESOLVER is not set
CONFIG_BATMAN_ADV=y
# CONFIG_BATMAN_ADV_NC is not set
# CONFIG_BATMAN_ADV_DEBUG is not set
CONFIG_OPENVSWITCH=y
CONFIG_VSOCKETS=y
# CONFIG_NETLINK_MMAP is not set
# CONFIG_NETLINK_DIAG is not set
CONFIG_NET_MPLS_GSO=y
CONFIG_NETPRIO_CGROUP=y
CONFIG_NET_RX_BUSY_POLL=y
CONFIG_BQL=y

#
# Network testing
#
# CONFIG_HAMRADIO is not set
CONFIG_CAN=y
CONFIG_CAN_RAW=y
# CONFIG_CAN_BCM is not set
CONFIG_CAN_GW=y

#
# CAN Device Drivers
#
CONFIG_CAN_VCAN=y
# CONFIG_CAN_SLCAN is not set
CONFIG_CAN_DEV=y
# CONFIG_CAN_CALC_BITTIMING is not set
# CONFIG_CAN_LEDS is not set
# CONFIG_CAN_MCP251X is not set
# CONFIG_PCH_CAN is not set
# CONFIG_CAN_GRCAN is not set
CONFIG_CAN_SJA1000=y
# CONFIG_CAN_SJA1000_ISA is not set
# CONFIG_CAN_SJA1000_PLATFORM is not set
CONFIG_CAN_SJA1000_OF_PLATFORM=y
# CONFIG_CAN_EMS_PCMCIA is not set
# CONFIG_CAN_EMS_PCI is not set
# CONFIG_CAN_PEAK_PCMCIA is not set
# CONFIG_CAN_PEAK_PCI is not set
# CONFIG_CAN_KVASER_PCI is not set
# CONFIG_CAN_PLX_PCI is not set
# CONFIG_CAN_C_CAN is not set
# CONFIG_CAN_CC770 is not set

#
# CAN USB interfaces
#
CONFIG_CAN_EMS_USB=y
# CONFIG_CAN_ESD_USB2 is not set
CONFIG_CAN_KVASER_USB=y
# CONFIG_CAN_PEAK_USB is not set
# CONFIG_CAN_8DEV_USB is not set
CONFIG_CAN_SOFTING=y
CONFIG_CAN_SOFTING_CS=y
# CONFIG_CAN_DEBUG_DEVICES is not set
CONFIG_IRDA=y

#
# IrDA protocols
#
CONFIG_IRLAN=y
# CONFIG_IRCOMM is not set
CONFIG_IRDA_ULTRA=y

#
# IrDA options
#
# CONFIG_IRDA_CACHE_LAST_LSAP is not set
# CONFIG_IRDA_FAST_RR is not set
# CONFIG_IRDA_DEBUG is not set

#
# Infrared-port device drivers
#

#
# SIR device drivers
#
CONFIG_IRTTY_SIR=y

#
# Dongle support
#
CONFIG_DONGLE=y
CONFIG_ESI_DONGLE=y
# CONFIG_ACTISYS_DONGLE is not set
CONFIG_TEKRAM_DONGLE=y
# CONFIG_TOIM3232_DONGLE is not set
CONFIG_LITELINK_DONGLE=y
CONFIG_MA600_DONGLE=y
CONFIG_GIRBIL_DONGLE=y
# CONFIG_MCP2120_DONGLE is not set
CONFIG_OLD_BELKIN_DONGLE=y
# CONFIG_ACT200L_DONGLE is not set
# CONFIG_KINGSUN_DONGLE is not set
# CONFIG_KSDAZZLE_DONGLE is not set
CONFIG_KS959_DONGLE=y

#
# FIR device drivers
#
CONFIG_USB_IRDA=y
CONFIG_SIGMATEL_FIR=y
CONFIG_NSC_FIR=y
CONFIG_WINBOND_FIR=y
# CONFIG_TOSHIBA_FIR is not set
CONFIG_SMC_IRCC_FIR=y
CONFIG_ALI_FIR=y
# CONFIG_VLSI_FIR is not set
CONFIG_VIA_FIR=y
# CONFIG_MCS_FIR is not set
CONFIG_BT=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
CONFIG_BT_BNEP=y
CONFIG_BT_BNEP_MC_FILTER=y
CONFIG_BT_BNEP_PROTO_FILTER=y
CONFIG_BT_HIDP=y

#
# Bluetooth device drivers
#
CONFIG_BT_HCIBTUSB=y
# CONFIG_BT_HCIBTSDIO is not set
# CONFIG_BT_HCIUART is not set
# CONFIG_BT_HCIBCM203X is not set
CONFIG_BT_HCIBPA10X=y
# CONFIG_BT_HCIBFUSB is not set
CONFIG_BT_HCIDTL1=y
CONFIG_BT_HCIBT3C=y
# CONFIG_BT_HCIBLUECARD is not set
# CONFIG_BT_HCIBTUART is not set
# CONFIG_BT_HCIVHCI is not set
CONFIG_BT_MRVL=y
# CONFIG_BT_MRVL_SDIO is not set
CONFIG_BT_ATH3K=y
CONFIG_BT_WILINK=y
CONFIG_FIB_RULES=y
CONFIG_WIRELESS=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_CFG80211=y
# CONFIG_NL80211_TESTMODE is not set
# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
# CONFIG_CFG80211_REG_DEBUG is not set
# CONFIG_CFG80211_DEFAULT_PS is not set
CONFIG_CFG80211_DEBUGFS=y
# CONFIG_CFG80211_INTERNAL_REGDB is not set
CONFIG_CFG80211_WEXT=y
# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
CONFIG_WIMAX=y
CONFIG_WIMAX_DEBUG_LEVEL=8
# CONFIG_RFKILL is not set
CONFIG_RFKILL_REGULATOR=y
CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y
# CONFIG_NET_9P_DEBUG is not set
CONFIG_CAIF=y
CONFIG_CAIF_DEBUG=y
# CONFIG_CAIF_NETDEV is not set
CONFIG_CAIF_USB=y
# CONFIG_NFC is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_DEVTMPFS=y
# CONFIG_DEVTMPFS_MOUNT is not set
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_EXTRA_FIRMWARE=""
CONFIG_FW_LOADER_USER_HELPER=y
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_GENERIC_CPU_DEVICES is not set
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_SPI=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_IRQ=y
CONFIG_DMA_SHARED_BUFFER=y

#
# Bus devices
#
CONFIG_CONNECTOR=y
# CONFIG_PROC_EVENTS is not set
CONFIG_MTD=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
CONFIG_MTD_REDBOOT_PARTS_READONLY=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
CONFIG_MTD_AR7_PARTS=y

#
# User Modules And Translation Layers
#
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
CONFIG_INFTL=y
CONFIG_RFD_FTL=y
CONFIG_SSFDC=y
CONFIG_SM_FTL=y
CONFIG_MTD_OOPS=y
CONFIG_MTD_SWAP=y

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
# CONFIG_MTD_CFI_AMDSTD is not set
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_RAM=y
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set

#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_COMPAT=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_PHYSMAP_OF is not set
CONFIG_MTD_SC520CDP=y
CONFIG_MTD_NETSC520=y
# CONFIG_MTD_TS5500 is not set
# CONFIG_MTD_AMD76XROM is not set
# CONFIG_MTD_ICHXROM is not set
# CONFIG_MTD_ESB2ROM is not set
# CONFIG_MTD_CK804XROM is not set
# CONFIG_MTD_SCB2_FLASH is not set
# CONFIG_MTD_NETtel is not set
CONFIG_MTD_L440GX=y
# CONFIG_MTD_PCI is not set
CONFIG_MTD_PCMCIA=y
CONFIG_MTD_PCMCIA_ANONYMOUS=y
# CONFIG_MTD_GPIO_ADDR is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
CONFIG_MTD_PLATRAM=y
# CONFIG_MTD_LATCH_ADDR is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_DATAFLASH is not set
# CONFIG_MTD_M25P80 is not set
# CONFIG_MTD_SST25L is not set
CONFIG_MTD_SLRAM=y
# CONFIG_MTD_PHRAM is not set
CONFIG_MTD_MTDRAM=y
CONFIG_MTDRAM_TOTAL_SIZE=4096
CONFIG_MTDRAM_ERASE_SIZE=128
CONFIG_MTDRAM_ABS_POS=0
CONFIG_MTD_BLOCK2MTD=y

#
# Disk-On-Chip Device Drivers
#
CONFIG_MTD_DOCG3=y
CONFIG_BCH_CONST_M=14
CONFIG_BCH_CONST_T=4
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_ECC_SMC=y
# CONFIG_MTD_NAND is not set
CONFIG_MTD_ONENAND=y
# CONFIG_MTD_ONENAND_VERIFY_WRITE is not set
CONFIG_MTD_ONENAND_GENERIC=y
CONFIG_MTD_ONENAND_OTP=y
CONFIG_MTD_ONENAND_2X_PROGRAM=y

#
# LPDDR flash memory drivers
#
CONFIG_MTD_LPDDR=y
CONFIG_MTD_QINFO_PROBE=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not set
CONFIG_OF=y

#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
CONFIG_OF_SELFTEST=y
CONFIG_OF_PROMTREE=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_IRQ=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_MTD=y
# CONFIG_PARPORT is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG_MESSAGES=y

#
# Protocols
#
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set

#
# DRBD disabled because PROC_FS or INET not selected
#
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_NVME is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_VIRTIO_BLK is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_BLK_DEV_RSXX is not set

#
# Misc devices
#
CONFIG_SENSORS_LIS3LV02D=y
CONFIG_AD525X_DPOT=y
# CONFIG_AD525X_DPOT_I2C is not set
CONFIG_AD525X_DPOT_SPI=y
CONFIG_DUMMY_IRQ=y
# CONFIG_IBM_ASM is not set
# CONFIG_PHANTOM is not set
# CONFIG_INTEL_MID_PTI is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
CONFIG_ICS932S401=y
CONFIG_ATMEL_SSC=y
CONFIG_ENCLOSURE_SERVICES=y
# CONFIG_HP_ILO is not set
CONFIG_APDS9802ALS=y
# CONFIG_ISL29003 is not set
CONFIG_ISL29020=y
CONFIG_SENSORS_TSL2550=y
# CONFIG_SENSORS_BH1780 is not set
CONFIG_SENSORS_BH1770=y
# CONFIG_SENSORS_APDS990X is not set
# CONFIG_HMC6352 is not set
# CONFIG_DS1682 is not set
# CONFIG_TI_DAC7512 is not set
# CONFIG_VMWARE_BALLOON is not set
CONFIG_BMP085=y
CONFIG_BMP085_I2C=y
CONFIG_BMP085_SPI=y
# CONFIG_PCH_PHUB is not set
CONFIG_USB_SWITCH_FSA9480=y
CONFIG_LATTICE_ECP3_CONFIG=y
# CONFIG_SRAM is not set
CONFIG_C2PORT=y
CONFIG_C2PORT_DURAMAR_2150=y

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_AT25 is not set
# CONFIG_EEPROM_LEGACY is not set
CONFIG_EEPROM_MAX6875=y
CONFIG_EEPROM_93CX6=y
CONFIG_EEPROM_93XX46=y
# CONFIG_CB710_CORE is not set

#
# Texas Instruments shared transport line discipline
#
CONFIG_TI_ST=y
CONFIG_SENSORS_LIS3_I2C=y

#
# Altera FPGA firmware download module
#
# CONFIG_ALTERA_STAPL is not set
# CONFIG_INTEL_MEI is not set
# CONFIG_INTEL_MEI_ME is not set
# CONFIG_VMWARE_VMCI is not set
CONFIG_HAVE_IDE=y
CONFIG_IDE=y

#
# Please see Documentation/ide/ide.txt for help/info on IDE drives
#
CONFIG_IDE_ATAPI=y
CONFIG_BLK_DEV_IDE_SATA=y
CONFIG_IDE_GD=y
CONFIG_IDE_GD_ATA=y
# CONFIG_IDE_GD_ATAPI is not set
CONFIG_BLK_DEV_IDECS=y
# CONFIG_BLK_DEV_DELKIN is not set
CONFIG_BLK_DEV_IDECD=y
CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
CONFIG_BLK_DEV_IDETAPE=y
# CONFIG_BLK_DEV_IDEACPI is not set
CONFIG_IDE_TASK_IOCTL=y
CONFIG_IDE_PROC_FS=y

#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_PLATFORM=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set

#
# PCI IDE chipsets support
#
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_ATIIXP is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_CS5535 is not set
# CONFIG_BLK_DEV_CS5536 is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_IT8172 is not set
# CONFIG_BLK_DEV_IT8213 is not set
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_BLK_DEV_IDEDMA is not set

#
# SCSI device support
#
CONFIG_SCSI_MOD=y
CONFIG_RAID_ATTRS=y
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y

#
# SCSI support type (disk, tape, CD-ROM)
#
# CONFIG_BLK_DEV_SD is not set
# CONFIG_CHR_DEV_ST is not set
CONFIG_CHR_DEV_OSST=y
CONFIG_BLK_DEV_SR=y
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=y
CONFIG_CHR_DEV_SCH=y
CONFIG_SCSI_ENCLOSURE=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_SCAN_ASYNC is not set

#
# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=y
CONFIG_SCSI_SAS_ATTRS=y
# CONFIG_SCSI_SAS_LIBSAS is not set
CONFIG_SCSI_SRP_ATTRS=y
# CONFIG_SCSI_LOWLEVEL is not set
CONFIG_SCSI_LOWLEVEL_PCMCIA=y
CONFIG_SCSI_DH=y
# CONFIG_SCSI_DH_RDAC is not set
CONFIG_SCSI_DH_HP_SW=y
CONFIG_SCSI_DH_EMC=y
CONFIG_SCSI_DH_ALUA=y
CONFIG_SCSI_OSD_INITIATOR=y
# CONFIG_SCSI_OSD_ULD is not set
CONFIG_SCSI_OSD_DPRINT_SENSE=1
CONFIG_SCSI_OSD_DEBUG=y
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_ATA_VERBOSE_ERROR is not set
CONFIG_ATA_ACPI=y
# CONFIG_SATA_ZPODD is not set
# CONFIG_SATA_PMP is not set

#
# Controllers with non-SFF native interface
#
# CONFIG_SATA_AHCI is not set
CONFIG_SATA_AHCI_PLATFORM=y
# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_ACARD_AHCI is not set
# CONFIG_SATA_SIL24 is not set
# CONFIG_ATA_SFF is not set
CONFIG_MD=y
# CONFIG_BLK_DEV_MD is not set
CONFIG_BCACHE=y
CONFIG_BCACHE_DEBUG=y
CONFIG_BCACHE_EDEBUG=y
# CONFIG_BCACHE_CLOSURES_DEBUG is not set
CONFIG_BLK_DEV_DM=y
# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=y
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_THIN_PROVISIONING is not set
# CONFIG_DM_CACHE is not set
CONFIG_DM_MIRROR=y
# CONFIG_DM_RAID is not set
CONFIG_DM_LOG_USERSPACE=y
CONFIG_DM_ZERO=y
# CONFIG_DM_MULTIPATH is not set
CONFIG_DM_DELAY=y
# CONFIG_DM_UEVENT is not set
CONFIG_DM_FLAKEY=y
# CONFIG_DM_VERITY is not set
CONFIG_DM_SWITCH=y
CONFIG_TARGET_CORE=y
CONFIG_TCM_IBLOCK=y
CONFIG_TCM_FILEIO=y
CONFIG_TCM_PSCSI=y
# CONFIG_LOOPBACK_TARGET is not set
CONFIG_ISCSI_TARGET=y
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#
# CONFIG_FIREWIRE is not set
# CONFIG_FIREWIRE_NOSY is not set
# CONFIG_I2O is not set
CONFIG_MACINTOSH_DRIVERS=y
CONFIG_MAC_EMUMOUSEBTN=y
# CONFIG_NETDEVICES is not set
CONFIG_VHOST_NET=y
CONFIG_VHOST_RING=y
CONFIG_VHOST=y

#
# Input device support
#
CONFIG_INPUT=y
CONFIG_INPUT_FF_MEMLESS=y
CONFIG_INPUT_POLLDEV=y
CONFIG_INPUT_SPARSEKMAP=y
CONFIG_INPUT_MATRIXKMAP=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_INPUT_JOYDEV=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=y

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ADP5520=y
CONFIG_KEYBOARD_ADP5588=y
CONFIG_KEYBOARD_ADP5589=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_QT1070 is not set
CONFIG_KEYBOARD_QT2160=y
CONFIG_KEYBOARD_LKKBD=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_KEYBOARD_GPIO_POLLED=y
CONFIG_KEYBOARD_TCA6416=y
# CONFIG_KEYBOARD_TCA8418 is not set
CONFIG_KEYBOARD_MATRIX=y
CONFIG_KEYBOARD_LM8323=y
CONFIG_KEYBOARD_LM8333=y
CONFIG_KEYBOARD_MAX7359=y
CONFIG_KEYBOARD_MCS=y
CONFIG_KEYBOARD_MPR121=y
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_KEYBOARD_OPENCORES=y
CONFIG_KEYBOARD_STOWAWAY=y
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_KEYBOARD_STMPE is not set
CONFIG_KEYBOARD_TWL4030=y
CONFIG_KEYBOARD_XTKBD=y
# CONFIG_KEYBOARD_CROS_EC is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_JOYSTICK=y
# CONFIG_JOYSTICK_ANALOG is not set
# CONFIG_JOYSTICK_A3D is not set
CONFIG_JOYSTICK_ADI=y
CONFIG_JOYSTICK_COBRA=y
# CONFIG_JOYSTICK_GF2K is not set
CONFIG_JOYSTICK_GRIP=y
CONFIG_JOYSTICK_GRIP_MP=y
# CONFIG_JOYSTICK_GUILLEMOT is not set
# CONFIG_JOYSTICK_INTERACT is not set
CONFIG_JOYSTICK_SIDEWINDER=y
CONFIG_JOYSTICK_TMDC=y
# CONFIG_JOYSTICK_IFORCE is not set
# CONFIG_JOYSTICK_WARRIOR is not set
# CONFIG_JOYSTICK_MAGELLAN is not set
CONFIG_JOYSTICK_SPACEORB=y
CONFIG_JOYSTICK_SPACEBALL=y
CONFIG_JOYSTICK_STINGER=y
# CONFIG_JOYSTICK_TWIDJOY is not set
CONFIG_JOYSTICK_ZHENHUA=y
CONFIG_JOYSTICK_AS5011=y
CONFIG_JOYSTICK_JOYDUMP=y
CONFIG_JOYSTICK_XPAD=y
CONFIG_JOYSTICK_XPAD_FF=y
# CONFIG_JOYSTICK_XPAD_LEDS is not set
CONFIG_INPUT_TABLET=y
CONFIG_TABLET_USB_ACECAD=y
CONFIG_TABLET_USB_AIPTEK=y
CONFIG_TABLET_USB_GTCO=y
CONFIG_TABLET_USB_HANWANG=y
CONFIG_TABLET_USB_KBTAB=y
CONFIG_TABLET_USB_WACOM=y
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_88PM860X=y
CONFIG_TOUCHSCREEN_ADS7846=y
CONFIG_TOUCHSCREEN_AD7877=y
# CONFIG_TOUCHSCREEN_AD7879 is not set
# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
CONFIG_TOUCHSCREEN_AUO_PIXCIR=y
CONFIG_TOUCHSCREEN_BU21013=y
CONFIG_TOUCHSCREEN_CY8CTMG110=y
CONFIG_TOUCHSCREEN_CYTTSP_CORE=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
CONFIG_TOUCHSCREEN_CYTTSP_SPI=y
# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
CONFIG_TOUCHSCREEN_DA9034=y
CONFIG_TOUCHSCREEN_DA9052=y
CONFIG_TOUCHSCREEN_DYNAPRO=y
CONFIG_TOUCHSCREEN_HAMPSHIRE=y
# CONFIG_TOUCHSCREEN_EETI is not set
CONFIG_TOUCHSCREEN_EGALAX=y
CONFIG_TOUCHSCREEN_FUJITSU=y
# CONFIG_TOUCHSCREEN_ILI210X is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
CONFIG_TOUCHSCREEN_ELO=y
CONFIG_TOUCHSCREEN_WACOM_W8001=y
CONFIG_TOUCHSCREEN_WACOM_I2C=y
CONFIG_TOUCHSCREEN_MAX11801=y
CONFIG_TOUCHSCREEN_MCS5000=y
# CONFIG_TOUCHSCREEN_MMS114 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
CONFIG_TOUCHSCREEN_PENMOUNT=y
# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
CONFIG_TOUCHSCREEN_TOUCHWIN=y
CONFIG_TOUCHSCREEN_TI_AM335X_TSC=y
CONFIG_TOUCHSCREEN_PIXCIR=y
CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
CONFIG_TOUCHSCREEN_MC13783=y
CONFIG_TOUCHSCREEN_USB_EGALAX=y
CONFIG_TOUCHSCREEN_USB_PANJIT=y
CONFIG_TOUCHSCREEN_USB_3M=y
CONFIG_TOUCHSCREEN_USB_ITM=y
CONFIG_TOUCHSCREEN_USB_ETURBO=y
CONFIG_TOUCHSCREEN_USB_GUNZE=y
CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
CONFIG_TOUCHSCREEN_USB_GOTOP=y
CONFIG_TOUCHSCREEN_USB_JASTEC=y
CONFIG_TOUCHSCREEN_USB_ELO=y
CONFIG_TOUCHSCREEN_USB_E2I=y
CONFIG_TOUCHSCREEN_USB_ZYTRONIC=y
CONFIG_TOUCHSCREEN_USB_ETT_TC45USB=y
CONFIG_TOUCHSCREEN_USB_NEXIO=y
CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
CONFIG_TOUCHSCREEN_TSC_SERIO=y
# CONFIG_TOUCHSCREEN_TSC2005 is not set
CONFIG_TOUCHSCREEN_TSC2007=y
CONFIG_TOUCHSCREEN_ST1232=y
CONFIG_TOUCHSCREEN_STMPE=y
# CONFIG_TOUCHSCREEN_TPS6507X is not set
CONFIG_INPUT_MISC=y
CONFIG_INPUT_88PM860X_ONKEY=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_ARIZONA_HAPTICS is not set
CONFIG_INPUT_BMA150=y
CONFIG_INPUT_PCSPKR=y
CONFIG_INPUT_MC13783_PWRBUTTON=y
# CONFIG_INPUT_MMA8450 is not set
CONFIG_INPUT_MPU3050=y
# CONFIG_INPUT_APANEL is not set
CONFIG_INPUT_GP2A=y
CONFIG_INPUT_GPIO_TILT_POLLED=y
CONFIG_INPUT_WISTRON_BTNS=y
# CONFIG_INPUT_ATLAS_BTNS is not set
CONFIG_INPUT_ATI_REMOTE2=y
CONFIG_INPUT_KEYSPAN_REMOTE=y
# CONFIG_INPUT_KXTJ9 is not set
# CONFIG_INPUT_POWERMATE is not set
CONFIG_INPUT_YEALINK=y
CONFIG_INPUT_CM109=y
# CONFIG_INPUT_RETU_PWRBUTTON is not set
# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
# CONFIG_INPUT_TWL4030_VIBRA is not set
# CONFIG_INPUT_UINPUT is not set
CONFIG_INPUT_PCF50633_PMU=y
# CONFIG_INPUT_PCF8574 is not set
# CONFIG_INPUT_PWM_BEEPER is not set
CONFIG_INPUT_GPIO_ROTARY_ENCODER=y
CONFIG_INPUT_DA9052_ONKEY=y
# CONFIG_INPUT_DA9055_ONKEY is not set
CONFIG_INPUT_ADXL34X=y
# CONFIG_INPUT_ADXL34X_I2C is not set
CONFIG_INPUT_ADXL34X_SPI=y
# CONFIG_INPUT_IMS_PCU is not set
# CONFIG_INPUT_CMA3000 is not set
# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set

#
# Hardware I/O ports
#
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PCIPS2 is not set
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=y
CONFIG_SERIO_ALTERA_PS2=y
# CONFIG_SERIO_PS2MULT is not set
CONFIG_SERIO_ARC_PS2=y
CONFIG_SERIO_APBPS2=y
# CONFIG_SERIO_OLPC_APSP is not set
CONFIG_GAMEPORT=y
CONFIG_GAMEPORT_NS558=y
# CONFIG_GAMEPORT_L4 is not set
# CONFIG_GAMEPORT_EMU10K1 is not set
# CONFIG_GAMEPORT_FM801 is not set

#
# Character devices
#
CONFIG_TTY=y
CONFIG_VT=y
CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_VT_CONSOLE_SLEEP=y
CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set
CONFIG_N_GSM=y
# CONFIG_TRACE_SINK is not set
# CONFIG_DEVKMEM is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_PNP=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_PCI=y
# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
# CONFIG_SERIAL_8250_MANY_PORTS is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_8250_DETECT_IRQ=y
CONFIG_SERIAL_8250_RSA=y
CONFIG_SERIAL_8250_DW=y

#
# Non-8250 serial port support
#
# CONFIG_SERIAL_MAX3100 is not set
# CONFIG_SERIAL_MAX310X is not set
# CONFIG_SERIAL_MFD_HSU is not set
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_SCCNXP=y
CONFIG_SERIAL_SCCNXP_CONSOLE=y
CONFIG_SERIAL_TIMBERDALE=y
CONFIG_SERIAL_ALTERA_JTAGUART=y
CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE=y
CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS=y
CONFIG_SERIAL_ALTERA_UART=y
CONFIG_SERIAL_ALTERA_UART_MAXPORTS=4
CONFIG_SERIAL_ALTERA_UART_BAUDRATE=115200
# CONFIG_SERIAL_ALTERA_UART_CONSOLE is not set
CONFIG_SERIAL_IFX6X60=y
# CONFIG_SERIAL_PCH_UART is not set
CONFIG_SERIAL_XILINX_PS_UART=y
CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
CONFIG_SERIAL_ARC=y
# CONFIG_SERIAL_ARC_CONSOLE is not set
CONFIG_SERIAL_ARC_NR_PORTS=1
# CONFIG_SERIAL_RP2 is not set
# CONFIG_SERIAL_FSL_LPUART is not set
CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_HVC_DRIVER=y
# CONFIG_VIRTIO_CONSOLE is not set
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=y
CONFIG_HW_RANDOM_INTEL=y
CONFIG_HW_RANDOM_AMD=y
CONFIG_HW_RANDOM_GEODE=y
CONFIG_HW_RANDOM_VIA=y
CONFIG_HW_RANDOM_VIRTIO=y
CONFIG_NVRAM=y
CONFIG_R3964=y
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set

#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
CONFIG_CARDMAN_4000=y
CONFIG_CARDMAN_4040=y
CONFIG_MWAVE=y
CONFIG_PC8736x_GPIO=y
CONFIG_NSC_GPIO=y
# CONFIG_RAW_DRIVER is not set
# CONFIG_HPET is not set
CONFIG_HANGCHECK_TIMER=y
# CONFIG_TCG_TPM is not set
CONFIG_TELCLOCK=y
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
# CONFIG_I2C_COMPAT is not set
# CONFIG_I2C_CHARDEV is not set
# CONFIG_I2C_MUX is not set
# CONFIG_I2C_HELPER_AUTO is not set
# CONFIG_I2C_SMBUS is not set

#
# I2C Algorithms
#
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_ALGOPCF=y
CONFIG_I2C_ALGOPCA=y

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_ISMT is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set

#
# ACPI drivers
#
# CONFIG_I2C_SCMI is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
CONFIG_I2C_CBUS_GPIO=y
# CONFIG_I2C_DESIGNWARE_PCI is not set
# CONFIG_I2C_EG20T is not set
CONFIG_I2C_GPIO=y
CONFIG_I2C_KEMPLD=y
CONFIG_I2C_OCORES=y
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_PXA is not set
# CONFIG_I2C_PXA_PCI is not set
# CONFIG_I2C_SIMTEC is not set
CONFIG_I2C_XILINX=y

#
# External I2C/SMBus adapter drivers
#
CONFIG_I2C_DIOLAN_U2C=y
# CONFIG_I2C_PARPORT_LIGHT is not set
CONFIG_I2C_TAOS_EVM=y
# CONFIG_I2C_TINY_USB is not set
# CONFIG_I2C_VIPERBOARD is not set

#
# Other I2C/SMBus bus drivers
#
# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
CONFIG_SPI=y
# CONFIG_SPI_DEBUG is not set
CONFIG_SPI_MASTER=y

#
# SPI Master Controller Drivers
#
CONFIG_SPI_ALTERA=y
# CONFIG_SPI_ATMEL is not set
CONFIG_SPI_BCM2835=y
CONFIG_SPI_BITBANG=y
# CONFIG_SPI_EP93XX is not set
CONFIG_SPI_GPIO=y
CONFIG_SPI_IMX=y
# CONFIG_SPI_FSL_SPI is not set
# CONFIG_SPI_FSL_DSPI is not set
CONFIG_SPI_OC_TINY=y
CONFIG_SPI_OMAP24XX=y
CONFIG_SPI_TI_QSPI=y
CONFIG_SPI_OMAP_100K=y
CONFIG_SPI_ORION=y
# CONFIG_SPI_PXA2XX is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_SC18IS602 is not set
# CONFIG_SPI_SH is not set
# CONFIG_SPI_SH_HSPI is not set
CONFIG_SPI_TEGRA114=y
CONFIG_SPI_TEGRA20_SFLASH=y
CONFIG_SPI_TEGRA20_SLINK=y
# CONFIG_SPI_TOPCLIFF_PCH is not set
CONFIG_SPI_TXX9=y
# CONFIG_SPI_XCOMM is not set
CONFIG_SPI_XILINX=y
CONFIG_SPI_DESIGNWARE=y
# CONFIG_SPI_DW_PCI is not set

#
# SPI Protocol Masters
#
# CONFIG_SPI_SPIDEV is not set
CONFIG_SPI_TLE62X0=y
CONFIG_HSI=y
CONFIG_HSI_BOARDINFO=y

#
# HSI clients
#
CONFIG_HSI_CHAR=y

#
# PPS support
#
CONFIG_PPS=y
# CONFIG_PPS_DEBUG is not set
CONFIG_NTP_PPS=y

#
# PPS clients support
#
CONFIG_PPS_CLIENT_KTIMER=y
CONFIG_PPS_CLIENT_LDISC=y
CONFIG_PPS_CLIENT_GPIO=y

#
# PPS generators support
#

#
# PTP clock support
#
CONFIG_PTP_1588_CLOCK=y

#
# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
#
# CONFIG_PTP_1588_CLOCK_PCH is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIOLIB=y
CONFIG_OF_GPIO=y
CONFIG_GPIO_ACPI=y
# CONFIG_DEBUG_GPIO is not set
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_DA9052=y
CONFIG_GPIO_DA9055=y
CONFIG_GPIO_MAX730X=y

#
# Memory mapped GPIO drivers:
#
CONFIG_GPIO_GENERIC_PLATFORM=y
# CONFIG_GPIO_IT8761E is not set
# CONFIG_GPIO_F7188X is not set
# CONFIG_GPIO_TS5500 is not set
# CONFIG_GPIO_SCH is not set
# CONFIG_GPIO_ICH is not set
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_LYNXPOINT is not set
CONFIG_GPIO_GRGPIO=y

#
# I2C GPIO expanders:
#
CONFIG_GPIO_ARIZONA=y
CONFIG_GPIO_MAX7300=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_MAX732X_IRQ=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_PCA953X_IRQ=y
CONFIG_GPIO_PCF857X=y
CONFIG_GPIO_SX150X=y
CONFIG_GPIO_STMPE=y
# CONFIG_GPIO_TPS65912 is not set
# CONFIG_GPIO_TWL4030 is not set
# CONFIG_GPIO_ADP5520 is not set
CONFIG_GPIO_ADP5588=y
CONFIG_GPIO_ADP5588_IRQ=y
CONFIG_GPIO_ADNP=y

#
# PCI GPIO expanders:
#
# CONFIG_GPIO_BT8XX is not set
# CONFIG_GPIO_AMD8111 is not set
# CONFIG_GPIO_LANGWELL is not set
# CONFIG_GPIO_PCH is not set
# CONFIG_GPIO_ML_IOH is not set
# CONFIG_GPIO_SODAVILLE is not set
# CONFIG_GPIO_RDC321X is not set

#
# SPI GPIO expanders:
#
CONFIG_GPIO_MAX7301=y
CONFIG_GPIO_MCP23S08=y
CONFIG_GPIO_MC33880=y
# CONFIG_GPIO_74X164 is not set

#
# AC97 GPIO expanders:
#

#
# LPC GPIO expanders:
#
CONFIG_GPIO_KEMPLD=y

#
# MODULbus GPIO expanders:
#

#
# USB GPIO expanders:
#
# CONFIG_GPIO_VIPERBOARD is not set
CONFIG_W1=y
# CONFIG_W1_CON is not set

#
# 1-wire Bus Masters
#
# CONFIG_W1_MASTER_MATROX is not set
# CONFIG_W1_MASTER_DS2490 is not set
CONFIG_W1_MASTER_DS2482=y
# CONFIG_W1_MASTER_DS1WM is not set
CONFIG_W1_MASTER_GPIO=y

#
# 1-wire Slaves
#
CONFIG_W1_SLAVE_THERM=y
CONFIG_W1_SLAVE_SMEM=y
CONFIG_W1_SLAVE_DS2408=y
# CONFIG_W1_SLAVE_DS2408_READBACK is not set
# CONFIG_W1_SLAVE_DS2413 is not set
CONFIG_W1_SLAVE_DS2423=y
CONFIG_W1_SLAVE_DS2431=y
CONFIG_W1_SLAVE_DS2433=y
# CONFIG_W1_SLAVE_DS2433_CRC is not set
CONFIG_W1_SLAVE_DS2760=y
CONFIG_W1_SLAVE_DS2780=y
CONFIG_W1_SLAVE_DS2781=y
CONFIG_W1_SLAVE_DS28E04=y
CONFIG_W1_SLAVE_BQ27000=y
CONFIG_POWER_SUPPLY=y
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_PDA_POWER=y
CONFIG_TEST_POWER=y
CONFIG_BATTERY_88PM860X=y
CONFIG_BATTERY_DS2760=y
# CONFIG_BATTERY_DS2780 is not set
CONFIG_BATTERY_DS2781=y
# CONFIG_BATTERY_DS2782 is not set
CONFIG_BATTERY_OLPC=y
CONFIG_BATTERY_SBS=y
CONFIG_BATTERY_BQ27x00=y
CONFIG_BATTERY_BQ27X00_I2C=y
# CONFIG_BATTERY_BQ27X00_PLATFORM is not set
CONFIG_BATTERY_DA9030=y
CONFIG_BATTERY_DA9052=y
CONFIG_BATTERY_MAX17040=y
# CONFIG_BATTERY_MAX17042 is not set
CONFIG_BATTERY_TWL4030_MADC=y
# CONFIG_CHARGER_88PM860X is not set
CONFIG_CHARGER_PCF50633=y
CONFIG_BATTERY_RX51=y
CONFIG_CHARGER_ISP1704=y
# CONFIG_CHARGER_MAX8903 is not set
# CONFIG_CHARGER_TWL4030 is not set
# CONFIG_CHARGER_LP8727 is not set
CONFIG_CHARGER_GPIO=y
# CONFIG_CHARGER_MAX8997 is not set
CONFIG_CHARGER_BQ2415X=y
CONFIG_CHARGER_BQ24190=y
CONFIG_CHARGER_SMB347=y
CONFIG_BATTERY_GOLDFISH=y
CONFIG_POWER_RESET=y
# CONFIG_POWER_RESET_GPIO is not set
CONFIG_POWER_AVS=y
CONFIG_HWMON=y
CONFIG_HWMON_VID=y
# CONFIG_HWMON_DEBUG_CHIP is not set

#
# Native drivers
#
CONFIG_SENSORS_ABITUGURU=y
CONFIG_SENSORS_ABITUGURU3=y
CONFIG_SENSORS_AD7314=y
CONFIG_SENSORS_AD7414=y
# CONFIG_SENSORS_AD7418 is not set
CONFIG_SENSORS_ADCXX=y
CONFIG_SENSORS_ADM1021=y
CONFIG_SENSORS_ADM1025=y
CONFIG_SENSORS_ADM1026=y
CONFIG_SENSORS_ADM1029=y
# CONFIG_SENSORS_ADM1031 is not set
CONFIG_SENSORS_ADM9240=y
CONFIG_SENSORS_ADT7X10=y
# CONFIG_SENSORS_ADT7310 is not set
CONFIG_SENSORS_ADT7410=y
# CONFIG_SENSORS_ADT7411 is not set
CONFIG_SENSORS_ADT7462=y
CONFIG_SENSORS_ADT7470=y
CONFIG_SENSORS_ADT7475=y
CONFIG_SENSORS_ASC7621=y
# CONFIG_SENSORS_K8TEMP is not set
# CONFIG_SENSORS_K10TEMP is not set
# CONFIG_SENSORS_FAM15H_POWER is not set
CONFIG_SENSORS_ASB100=y
CONFIG_SENSORS_ATXP1=y
# CONFIG_SENSORS_DS620 is not set
CONFIG_SENSORS_DS1621=y
CONFIG_SENSORS_DA9052_ADC=y
CONFIG_SENSORS_DA9055=y
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
CONFIG_SENSORS_F71882FG=y
CONFIG_SENSORS_F75375S=y
# CONFIG_SENSORS_FSCHMD is not set
# CONFIG_SENSORS_G760A is not set
CONFIG_SENSORS_G762=y
CONFIG_SENSORS_GL518SM=y
# CONFIG_SENSORS_GL520SM is not set
CONFIG_SENSORS_GPIO_FAN=y
CONFIG_SENSORS_HIH6130=y
CONFIG_SENSORS_HTU21=y
CONFIG_SENSORS_CORETEMP=y
CONFIG_SENSORS_IT87=y
CONFIG_SENSORS_JC42=y
# CONFIG_SENSORS_LINEAGE is not set
# CONFIG_SENSORS_LM63 is not set
CONFIG_SENSORS_LM70=y
# CONFIG_SENSORS_LM73 is not set
CONFIG_SENSORS_LM75=y
CONFIG_SENSORS_LM77=y
CONFIG_SENSORS_LM78=y
CONFIG_SENSORS_LM80=y
CONFIG_SENSORS_LM83=y
CONFIG_SENSORS_LM85=y
CONFIG_SENSORS_LM87=y
# CONFIG_SENSORS_LM90 is not set
CONFIG_SENSORS_LM92=y
CONFIG_SENSORS_LM93=y
# CONFIG_SENSORS_LTC4151 is not set
CONFIG_SENSORS_LTC4215=y
CONFIG_SENSORS_LTC4245=y
# CONFIG_SENSORS_LTC4261 is not set
CONFIG_SENSORS_LM95234=y
CONFIG_SENSORS_LM95241=y
CONFIG_SENSORS_LM95245=y
CONFIG_SENSORS_MAX1111=y
# CONFIG_SENSORS_MAX16065 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX1668 is not set
CONFIG_SENSORS_MAX197=y
CONFIG_SENSORS_MAX6639=y
# CONFIG_SENSORS_MAX6642 is not set
CONFIG_SENSORS_MAX6650=y
CONFIG_SENSORS_MAX6697=y
CONFIG_SENSORS_MCP3021=y
# CONFIG_SENSORS_NCT6775 is not set
# CONFIG_SENSORS_PC87360 is not set
CONFIG_SENSORS_PC87427=y
CONFIG_SENSORS_PCF8591=y
CONFIG_PMBUS=y
CONFIG_SENSORS_PMBUS=y
CONFIG_SENSORS_ADM1275=y
CONFIG_SENSORS_LM25066=y
# CONFIG_SENSORS_LTC2978 is not set
# CONFIG_SENSORS_MAX16064 is not set
CONFIG_SENSORS_MAX34440=y
CONFIG_SENSORS_MAX8688=y
CONFIG_SENSORS_UCD9000=y
CONFIG_SENSORS_UCD9200=y
# CONFIG_SENSORS_ZL6100 is not set
# CONFIG_SENSORS_SHT15 is not set
CONFIG_SENSORS_SHT21=y
# CONFIG_SENSORS_SIS5595 is not set
CONFIG_SENSORS_SMM665=y
CONFIG_SENSORS_DME1737=y
CONFIG_SENSORS_EMC1403=y
CONFIG_SENSORS_EMC2103=y
# CONFIG_SENSORS_EMC6W201 is not set
CONFIG_SENSORS_SMSC47M1=y
# CONFIG_SENSORS_SMSC47M192 is not set
CONFIG_SENSORS_SMSC47B397=y
CONFIG_SENSORS_SCH56XX_COMMON=y
CONFIG_SENSORS_SCH5627=y
CONFIG_SENSORS_SCH5636=y
CONFIG_SENSORS_ADS1015=y
CONFIG_SENSORS_ADS7828=y
# CONFIG_SENSORS_ADS7871 is not set
CONFIG_SENSORS_AMC6821=y
CONFIG_SENSORS_INA209=y
# CONFIG_SENSORS_INA2XX is not set
CONFIG_SENSORS_THMC50=y
CONFIG_SENSORS_TMP102=y
# CONFIG_SENSORS_TMP401 is not set
# CONFIG_SENSORS_TMP421 is not set
# CONFIG_SENSORS_TWL4030_MADC is not set
CONFIG_SENSORS_VIA_CPUTEMP=y
# CONFIG_SENSORS_VIA686A is not set
CONFIG_SENSORS_VT1211=y
# CONFIG_SENSORS_VT8231 is not set
CONFIG_SENSORS_W83781D=y
CONFIG_SENSORS_W83791D=y
CONFIG_SENSORS_W83792D=y
CONFIG_SENSORS_W83793=y
CONFIG_SENSORS_W83795=y
CONFIG_SENSORS_W83795_FANCTRL=y
CONFIG_SENSORS_W83L785TS=y
# CONFIG_SENSORS_W83L786NG is not set
CONFIG_SENSORS_W83627HF=y
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_SENSORS_APPLESMC is not set
CONFIG_SENSORS_MC13783_ADC=y

#
# ACPI drivers
#
# CONFIG_SENSORS_ACPI_POWER is not set
# CONFIG_SENSORS_ATK0110 is not set
CONFIG_THERMAL=y
# CONFIG_THERMAL_HWMON is not set
# CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=y
CONFIG_THERMAL_GOV_FAIR_SHARE=y
# CONFIG_THERMAL_GOV_STEP_WISE is not set
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_THERMAL_EMULATION=y
CONFIG_INTEL_POWERCLAMP=y

#
# Texas Instruments thermal drivers
#
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y
CONFIG_WATCHDOG_NOWAYOUT=y

#
# Watchdog Device Drivers
#
CONFIG_SOFT_WATCHDOG=y
# CONFIG_DA9052_WATCHDOG is not set
# CONFIG_DA9055_WATCHDOG is not set
CONFIG_TWL4030_WATCHDOG=y
CONFIG_RETU_WATCHDOG=y
CONFIG_ACQUIRE_WDT=y
CONFIG_ADVANTECH_WDT=y
# CONFIG_ALIM1535_WDT is not set
# CONFIG_ALIM7101_WDT is not set
CONFIG_F71808E_WDT=y
# CONFIG_SP5100_TCO is not set
# CONFIG_SC520_WDT is not set
# CONFIG_SBC_FITPC2_WATCHDOG is not set
# CONFIG_EUROTECH_WDT is not set
# CONFIG_IB700_WDT is not set
CONFIG_IBMASR=y
CONFIG_WAFER_WDT=y
# CONFIG_I6300ESB_WDT is not set
# CONFIG_IE6XX_WDT is not set
# CONFIG_ITCO_WDT is not set
CONFIG_IT8712F_WDT=y
CONFIG_IT87_WDT=y
# CONFIG_HP_WATCHDOG is not set
CONFIG_KEMPLD_WDT=y
# CONFIG_SC1200_WDT is not set
CONFIG_PC87413_WDT=y
# CONFIG_NV_TCO is not set
# CONFIG_RDC321X_WDT is not set
CONFIG_60XX_WDT=y
CONFIG_SBC8360_WDT=y
# CONFIG_SBC7240_WDT is not set
CONFIG_CPU5_WDT=y
CONFIG_SMSC_SCH311X_WDT=y
# CONFIG_SMSC37B787_WDT is not set
# CONFIG_VIA_WDT is not set
# CONFIG_W83627HF_WDT is not set
CONFIG_W83697HF_WDT=y
CONFIG_W83697UG_WDT=y
# CONFIG_W83877F_WDT is not set
CONFIG_W83977F_WDT=y
CONFIG_MACHZ_WDT=y
# CONFIG_SBC_EPX_C3_WATCHDOG is not set
CONFIG_MEN_A21_WDT=y

#
# PCI-based Watchdog Cards
#
# CONFIG_PCIPCWATCHDOG is not set
# CONFIG_WDTPCI is not set

#
# USB-based Watchdog Cards
#
CONFIG_USBPCWATCHDOG=y
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
CONFIG_BCMA_POSSIBLE=y

#
# Broadcom specific AMBA
#
# CONFIG_BCMA is not set

#
# Multifunction device drivers
#
CONFIG_MFD_CORE=y
# CONFIG_MFD_CS5535 is not set
# CONFIG_MFD_AS3711 is not set
CONFIG_PMIC_ADP5520=y
CONFIG_MFD_AAT2870_CORE=y
CONFIG_MFD_CROS_EC=y
CONFIG_MFD_CROS_EC_I2C=y
# CONFIG_MFD_CROS_EC_SPI is not set
CONFIG_PMIC_DA903X=y
CONFIG_PMIC_DA9052=y
CONFIG_MFD_DA9052_SPI=y
CONFIG_MFD_DA9052_I2C=y
CONFIG_MFD_DA9055=y
# CONFIG_MFD_DA9063 is not set
CONFIG_MFD_MC13783=y
CONFIG_MFD_MC13XXX=y
CONFIG_MFD_MC13XXX_SPI=y
CONFIG_MFD_MC13XXX_I2C=y
CONFIG_HTC_PASIC3=y
# CONFIG_HTC_I2CPLD is not set
# CONFIG_LPC_ICH is not set
# CONFIG_LPC_SCH is not set
# CONFIG_MFD_JANZ_CMODIO is not set
CONFIG_MFD_KEMPLD=y
# CONFIG_MFD_88PM800 is not set
# CONFIG_MFD_88PM805 is not set
CONFIG_MFD_88PM860X=y
CONFIG_MFD_MAX77686=y
# CONFIG_MFD_MAX77693 is not set
CONFIG_MFD_MAX8907=y
# CONFIG_MFD_MAX8925 is not set
CONFIG_MFD_MAX8997=y
CONFIG_MFD_MAX8998=y
# CONFIG_EZX_PCAP is not set
CONFIG_MFD_VIPERBOARD=y
CONFIG_MFD_RETU=y
CONFIG_MFD_PCF50633=y
# CONFIG_PCF50633_ADC is not set
# CONFIG_PCF50633_GPIO is not set
# CONFIG_MFD_RDC321X is not set
# CONFIG_MFD_RTSX_PCI is not set
# CONFIG_MFD_RC5T583 is not set
# CONFIG_MFD_SEC_CORE is not set
CONFIG_MFD_SI476X_CORE=y
CONFIG_MFD_SM501=y
CONFIG_MFD_SM501_GPIO=y
# CONFIG_MFD_SMSC is not set
CONFIG_ABX500_CORE=y
# CONFIG_AB3100_CORE is not set
CONFIG_MFD_STMPE=y

#
# STMicroelectronics STMPE Interface Drivers
#
CONFIG_STMPE_I2C=y
CONFIG_STMPE_SPI=y
# CONFIG_MFD_SYSCON is not set
CONFIG_MFD_TI_AM335X_TSCADC=y
# CONFIG_MFD_LP8788 is not set
# CONFIG_MFD_PALMAS is not set
# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
CONFIG_TPS6507X=y
# CONFIG_MFD_TPS65090 is not set
CONFIG_MFD_TPS65217=y
# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_TPS65910 is not set
CONFIG_MFD_TPS65912=y
CONFIG_MFD_TPS65912_I2C=y
CONFIG_MFD_TPS65912_SPI=y
# CONFIG_MFD_TPS80031 is not set
CONFIG_TWL4030_CORE=y
CONFIG_TWL4030_MADC=y
CONFIG_MFD_TWL4030_AUDIO=y
# CONFIG_TWL6040_CORE is not set
CONFIG_MFD_WL1273_CORE=y
CONFIG_MFD_LM3533=y
# CONFIG_MFD_TIMBERDALE is not set
# CONFIG_MFD_TC3589X is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_MFD_VX855 is not set
CONFIG_MFD_ARIZONA=y
CONFIG_MFD_ARIZONA_I2C=y
# CONFIG_MFD_ARIZONA_SPI is not set
CONFIG_MFD_WM5102=y
# CONFIG_MFD_WM5110 is not set
CONFIG_MFD_WM8997=y
CONFIG_MFD_WM8400=y
# CONFIG_MFD_WM831X_I2C is not set
# CONFIG_MFD_WM831X_SPI is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_WM8994 is not set
CONFIG_REGULATOR=y
# CONFIG_REGULATOR_DEBUG is not set
CONFIG_REGULATOR_DUMMY=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
# CONFIG_REGULATOR_88PM8607 is not set
# CONFIG_REGULATOR_AD5398 is not set
CONFIG_REGULATOR_AAT2870=y
CONFIG_REGULATOR_ARIZONA=y
# CONFIG_REGULATOR_DA903X is not set
# CONFIG_REGULATOR_DA9052 is not set
CONFIG_REGULATOR_DA9055=y
CONFIG_REGULATOR_DA9210=y
# CONFIG_REGULATOR_FAN53555 is not set
CONFIG_REGULATOR_GPIO=y
# CONFIG_REGULATOR_ISL6271A is not set
CONFIG_REGULATOR_LP3971=y
CONFIG_REGULATOR_LP3972=y
CONFIG_REGULATOR_LP872X=y
CONFIG_REGULATOR_LP8755=y
CONFIG_REGULATOR_MAX1586=y
# CONFIG_REGULATOR_MAX8649 is not set
# CONFIG_REGULATOR_MAX8660 is not set
CONFIG_REGULATOR_MAX8907=y
# CONFIG_REGULATOR_MAX8952 is not set
CONFIG_REGULATOR_MAX8973=y
CONFIG_REGULATOR_MAX8997=y
# CONFIG_REGULATOR_MAX8998 is not set
CONFIG_REGULATOR_MAX77686=y
# CONFIG_REGULATOR_MC13783 is not set
# CONFIG_REGULATOR_MC13892 is not set
CONFIG_REGULATOR_PCF50633=y
CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_TPS51632=y
# CONFIG_REGULATOR_TPS62360 is not set
CONFIG_REGULATOR_TPS65023=y
CONFIG_REGULATOR_TPS6507X=y
CONFIG_REGULATOR_TPS65217=y
CONFIG_REGULATOR_TPS6524X=y
CONFIG_REGULATOR_TPS65912=y
CONFIG_REGULATOR_TWL4030=y
CONFIG_REGULATOR_WM8400=y
# CONFIG_MEDIA_SUPPORT is not set

#
# Graphics support
#
# CONFIG_AGP is not set
CONFIG_VGA_ARB=y
CONFIG_VGA_ARB_MAX_GPUS=16
# CONFIG_VGA_SWITCHEROO is not set
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
# CONFIG_DRM_RADEON is not set
# CONFIG_DRM_NOUVEAU is not set
# CONFIG_DRM_MGA is not set
# CONFIG_DRM_VIA is not set
# CONFIG_DRM_SAVAGE is not set
# CONFIG_DRM_VMWGFX is not set
# CONFIG_DRM_GMA500 is not set
# CONFIG_DRM_UDL is not set
# CONFIG_DRM_AST is not set
# CONFIG_DRM_MGAG200 is not set
# CONFIG_DRM_CIRRUS_QEMU is not set
# CONFIG_DRM_QXL is not set
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_HDMI=y
CONFIG_FB=y
# CONFIG_FIRMWARE_EDID is not set
# CONFIG_FB_DDC is not set
CONFIG_FB_BOOT_VESA_SUPPORT=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
CONFIG_FB_SYS_FILLRECT=y
CONFIG_FB_SYS_COPYAREA=y
CONFIG_FB_SYS_IMAGEBLIT=y
CONFIG_FB_FOREIGN_ENDIAN=y
# CONFIG_FB_BOTH_ENDIAN is not set
CONFIG_FB_BIG_ENDIAN=y
# CONFIG_FB_LITTLE_ENDIAN is not set
CONFIG_FB_SYS_FOPS=y
CONFIG_FB_DEFERRED_IO=y
# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_TILEBLITTING is not set

#
# Frame buffer hardware drivers
#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_ARC is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_UVESA=y
CONFIG_FB_VESA=y
# CONFIG_FB_N411 is not set
# CONFIG_FB_HGA is not set
CONFIG_FB_S1D13XXX=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I740 is not set
# CONFIG_FB_LE80578 is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_VIA is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_CARMINE is not set
# CONFIG_FB_GEODE is not set
CONFIG_FB_TMIO=y
# CONFIG_FB_TMIO_ACCELL is not set
CONFIG_FB_SM501=y
CONFIG_FB_SMSCUFX=y
CONFIG_FB_UDL=y
CONFIG_FB_GOLDFISH=y
CONFIG_FB_VIRTUAL=y
CONFIG_FB_METRONOME=y
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
# CONFIG_FB_AUO_K190X is not set
CONFIG_FB_SIMPLE=y
CONFIG_EXYNOS_VIDEO=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_LCD_L4F00242T03=y
CONFIG_LCD_LMS283GF05=y
CONFIG_LCD_LTV350QV=y
CONFIG_LCD_ILI922X=y
CONFIG_LCD_ILI9320=y
CONFIG_LCD_TDO24M=y
CONFIG_LCD_VGG2432A4=y
# CONFIG_LCD_PLATFORM is not set
CONFIG_LCD_S6E63M0=y
CONFIG_LCD_LD9040=y
CONFIG_LCD_AMS369FG06=y
CONFIG_LCD_LMS501KF03=y
# CONFIG_LCD_HX8357 is not set
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_GENERIC=y
# CONFIG_BACKLIGHT_LM3533 is not set
CONFIG_BACKLIGHT_PWM=y
CONFIG_BACKLIGHT_DA903X=y
CONFIG_BACKLIGHT_DA9052=y
# CONFIG_BACKLIGHT_APPLE is not set
CONFIG_BACKLIGHT_SAHARA=y
CONFIG_BACKLIGHT_ADP5520=y
CONFIG_BACKLIGHT_ADP8860=y
# CONFIG_BACKLIGHT_ADP8870 is not set
# CONFIG_BACKLIGHT_88PM860X is not set
CONFIG_BACKLIGHT_PCF50633=y
CONFIG_BACKLIGHT_AAT2870=y
CONFIG_BACKLIGHT_LM3630=y
CONFIG_BACKLIGHT_LM3639=y
CONFIG_BACKLIGHT_LP855X=y
# CONFIG_BACKLIGHT_PANDORA is not set
CONFIG_BACKLIGHT_TPS65217=y
# CONFIG_BACKLIGHT_GPIO is not set
CONFIG_BACKLIGHT_LV5207LP=y
CONFIG_BACKLIGHT_BD6107=y

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_FB_SSD1307=y
CONFIG_SOUND=y
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
CONFIG_SND_DMAENGINE_PCM=y
CONFIG_SND_RAWMIDI=y
CONFIG_SND_COMPRESS_OFFLOAD=y
CONFIG_SND_JACK=y
# CONFIG_SND_SEQUENCER is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
# CONFIG_SND_PCM_OSS is not set
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
# CONFIG_SND_PCM_XRUN_DEBUG is not set
CONFIG_SND_DMA_SGBUF=y
# CONFIG_SND_RAWMIDI_SEQ is not set
# CONFIG_SND_OPL3_LIB_SEQ is not set
# CONFIG_SND_OPL4_LIB_SEQ is not set
# CONFIG_SND_SBAWE_SEQ is not set
# CONFIG_SND_EMU10K1_SEQ is not set
# CONFIG_SND_DRIVERS is not set
CONFIG_SND_PCI=y
# CONFIG_SND_AD1889 is not set
# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ASIHPI is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
# CONFIG_SND_AU8810 is not set
# CONFIG_SND_AU8820 is not set
# CONFIG_SND_AU8830 is not set
# CONFIG_SND_AW2 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_BT87X is not set
# CONFIG_SND_CA0106 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_OXYGEN is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS5530 is not set
# CONFIG_SND_CS5535AUDIO is not set
# CONFIG_SND_CTXFI is not set
# CONFIG_SND_DARLA20 is not set
# CONFIG_SND_GINA20 is not set
# CONFIG_SND_LAYLA20 is not set
# CONFIG_SND_DARLA24 is not set
# CONFIG_SND_GINA24 is not set
# CONFIG_SND_LAYLA24 is not set
# CONFIG_SND_MONA is not set
# CONFIG_SND_MIA is not set
# CONFIG_SND_ECHO3G is not set
# CONFIG_SND_INDIGO is not set
# CONFIG_SND_INDIGOIO is not set
# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_INDIGOIOX is not set
# CONFIG_SND_INDIGODJX is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_FM801 is not set
# CONFIG_SND_HDA_INTEL is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_HDSPM is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_LOLA is not set
# CONFIG_SND_LX6464ES is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_SIS7019 is not set
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VIRTUOSO is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_SPI is not set
# CONFIG_SND_USB is not set
# CONFIG_SND_PCMCIA is not set
CONFIG_SND_SOC=y
CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
CONFIG_SND_ATMEL_SOC=y
# CONFIG_SND_IMX_SOC is not set
CONFIG_SND_KIRKWOOD_SOC=y
# CONFIG_SND_KIRKWOOD_SOC_OPENRD is not set
# CONFIG_SND_KIRKWOOD_SOC_T5325 is not set
CONFIG_SND_SOC_TEGRA=y
CONFIG_SND_SOC_TEGRA_RT5640=y
# CONFIG_SND_SOC_TEGRA_WM8753 is not set
CONFIG_SND_SOC_TEGRA_WM8903=y
CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
CONFIG_SND_SOC_TEGRA_ALC5632=y
CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_SOC_ALL_CODECS=y
CONFIG_SND_SOC_88PM860X=y
CONFIG_SND_SOC_ARIZONA=y
CONFIG_SND_SOC_WM_HUBS=y
CONFIG_SND_SOC_WM_ADSP=y
CONFIG_SND_SOC_AB8500_CODEC=y
CONFIG_SND_SOC_AD1836=y
CONFIG_SND_SOC_AD193X=y
CONFIG_SND_SOC_AD73311=y
CONFIG_SND_SOC_ADAU1701=y
CONFIG_SND_SOC_ADAU1373=y
CONFIG_SND_SOC_ADAV80X=y
CONFIG_SND_SOC_ADS117X=y
CONFIG_SND_SOC_AK4104=y
CONFIG_SND_SOC_AK4535=y
CONFIG_SND_SOC_AK4641=y
CONFIG_SND_SOC_AK4642=y
CONFIG_SND_SOC_AK4671=y
CONFIG_SND_SOC_AK5386=y
CONFIG_SND_SOC_ALC5623=y
CONFIG_SND_SOC_ALC5632=y
CONFIG_SND_SOC_CS42L51=y
CONFIG_SND_SOC_CS42L52=y
CONFIG_SND_SOC_CS42L73=y
CONFIG_SND_SOC_CS4270=y
CONFIG_SND_SOC_CS4271=y
CONFIG_SND_SOC_CX20442=y
CONFIG_SND_SOC_JZ4740_CODEC=y
CONFIG_SND_SOC_L3=y
CONFIG_SND_SOC_DA7210=y
CONFIG_SND_SOC_DA7213=y
CONFIG_SND_SOC_DA732X=y
CONFIG_SND_SOC_DA9055=y
CONFIG_SND_SOC_BT_SCO=y
CONFIG_SND_SOC_ISABELLE=y
CONFIG_SND_SOC_LM49453=y
CONFIG_SND_SOC_MAX98088=y
CONFIG_SND_SOC_MAX98090=y
CONFIG_SND_SOC_MAX98095=y
CONFIG_SND_SOC_MAX9850=y
CONFIG_SND_SOC_HDMI_CODEC=y
CONFIG_SND_SOC_PCM1681=y
CONFIG_SND_SOC_PCM1792A=y
CONFIG_SND_SOC_PCM3008=y
CONFIG_SND_SOC_RT5631=y
CONFIG_SND_SOC_RT5640=y
CONFIG_SND_SOC_SGTL5000=y
CONFIG_SND_SOC_SI476X=y
CONFIG_SND_SOC_SIGMADSP=y
CONFIG_SND_SOC_SPDIF=y
CONFIG_SND_SOC_SSM2518=y
CONFIG_SND_SOC_SSM2602=y
CONFIG_SND_SOC_STA32X=y
CONFIG_SND_SOC_STA529=y
CONFIG_SND_SOC_TAS5086=y
CONFIG_SND_SOC_TLV320AIC23=y
CONFIG_SND_SOC_TLV320AIC26=y
CONFIG_SND_SOC_TLV320AIC32X4=y
CONFIG_SND_SOC_TLV320AIC3X=y
CONFIG_SND_SOC_TLV320DAC33=y
CONFIG_SND_SOC_TWL4030=y
CONFIG_SND_SOC_UDA134X=y
CONFIG_SND_SOC_UDA1380=y
CONFIG_SND_SOC_WL1273=y
CONFIG_SND_SOC_WM0010=y
CONFIG_SND_SOC_WM1250_EV1=y
CONFIG_SND_SOC_WM2000=y
CONFIG_SND_SOC_WM2200=y
CONFIG_SND_SOC_WM5100=y
CONFIG_SND_SOC_WM5102=y
CONFIG_SND_SOC_WM8400=y
CONFIG_SND_SOC_WM8510=y
CONFIG_SND_SOC_WM8523=y
CONFIG_SND_SOC_WM8580=y
CONFIG_SND_SOC_WM8711=y
CONFIG_SND_SOC_WM8727=y
CONFIG_SND_SOC_WM8728=y
CONFIG_SND_SOC_WM8731=y
CONFIG_SND_SOC_WM8737=y
CONFIG_SND_SOC_WM8741=y
CONFIG_SND_SOC_WM8750=y
CONFIG_SND_SOC_WM8753=y
CONFIG_SND_SOC_WM8770=y
CONFIG_SND_SOC_WM8776=y
CONFIG_SND_SOC_WM8782=y
CONFIG_SND_SOC_WM8804=y
CONFIG_SND_SOC_WM8900=y
CONFIG_SND_SOC_WM8903=y
CONFIG_SND_SOC_WM8904=y
CONFIG_SND_SOC_WM8940=y
CONFIG_SND_SOC_WM8955=y
CONFIG_SND_SOC_WM8960=y
CONFIG_SND_SOC_WM8961=y
CONFIG_SND_SOC_WM8962=y
CONFIG_SND_SOC_WM8971=y
CONFIG_SND_SOC_WM8974=y
CONFIG_SND_SOC_WM8978=y
CONFIG_SND_SOC_WM8983=y
CONFIG_SND_SOC_WM8985=y
CONFIG_SND_SOC_WM8988=y
CONFIG_SND_SOC_WM8990=y
CONFIG_SND_SOC_WM8991=y
CONFIG_SND_SOC_WM8993=y
CONFIG_SND_SOC_WM8995=y
CONFIG_SND_SOC_WM8996=y
CONFIG_SND_SOC_WM8997=y
CONFIG_SND_SOC_WM9081=y
CONFIG_SND_SOC_WM9090=y
CONFIG_SND_SOC_LM4857=y
CONFIG_SND_SOC_MAX9768=y
CONFIG_SND_SOC_MAX9877=y
CONFIG_SND_SOC_MC13783=y
CONFIG_SND_SOC_ML26124=y
CONFIG_SND_SOC_TPA6130A2=y
CONFIG_SND_SIMPLE_CARD=y
CONFIG_SOUND_PRIME=y
CONFIG_SOUND_OSS=y
# CONFIG_SOUND_TRACEINIT is not set
# CONFIG_SOUND_DMAP is not set
# CONFIG_SOUND_VMIDI is not set
CONFIG_SOUND_TRIX=y
# CONFIG_TRIX_HAVE_BOOT is not set
CONFIG_SOUND_MSS=y
CONFIG_SOUND_MPU401=y
# CONFIG_SOUND_PAS is not set
CONFIG_SOUND_PSS=y
# CONFIG_PSS_MIXER is not set
# CONFIG_PSS_HAVE_BOOT is not set
CONFIG_SOUND_SB=y
# CONFIG_SOUND_YM3812 is not set
# CONFIG_SOUND_UART6850 is not set
CONFIG_SOUND_AEDSP16=y
# CONFIG_SC6600 is not set
CONFIG_SOUND_KAHLUA=y

#
# HID support
#
CONFIG_HID=y
# CONFIG_HID_BATTERY_STRENGTH is not set
# CONFIG_HIDRAW is not set
CONFIG_UHID=y
CONFIG_HID_GENERIC=y

#
# Special HID drivers
#
CONFIG_HID_A4TECH=y
# CONFIG_HID_ACRUX is not set
CONFIG_HID_APPLE=y
CONFIG_HID_AUREAL=y
CONFIG_HID_BELKIN=y
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
CONFIG_HID_PRODIKEYS=y
CONFIG_HID_CYPRESS=y
CONFIG_HID_DRAGONRISE=y
# CONFIG_DRAGONRISE_FF is not set
CONFIG_HID_EMS_FF=y
CONFIG_HID_ELECOM=y
CONFIG_HID_EZKEY=y
# CONFIG_HID_KEYTOUCH is not set
# CONFIG_HID_KYE is not set
CONFIG_HID_UCLOGIC=y
# CONFIG_HID_WALTOP is not set
CONFIG_HID_GYRATION=y
CONFIG_HID_ICADE=y
# CONFIG_HID_TWINHAN is not set
CONFIG_HID_KENSINGTON=y
CONFIG_HID_LCPOWER=y
CONFIG_HID_LOGITECH=y
# CONFIG_HID_LOGITECH_DJ is not set
CONFIG_LOGITECH_FF=y
CONFIG_LOGIRUMBLEPAD2_FF=y
# CONFIG_LOGIG940_FF is not set
CONFIG_LOGIWHEELS_FF=y
# CONFIG_HID_MAGICMOUSE is not set
CONFIG_HID_MICROSOFT=y
CONFIG_HID_MONTEREY=y
CONFIG_HID_MULTITOUCH=y
# CONFIG_HID_ORTEK is not set
CONFIG_HID_PANTHERLORD=y
CONFIG_PANTHERLORD_FF=y
# CONFIG_HID_PETALYNX is not set
CONFIG_HID_PICOLCD=y
CONFIG_HID_PICOLCD_FB=y
CONFIG_HID_PICOLCD_BACKLIGHT=y
CONFIG_HID_PICOLCD_LCD=y
CONFIG_HID_PICOLCD_LEDS=y
CONFIG_HID_PRIMAX=y
# CONFIG_HID_SAITEK is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SPEEDLINK=y
# CONFIG_HID_STEELSERIES is not set
# CONFIG_HID_SUNPLUS is not set
CONFIG_HID_GREENASIA=y
CONFIG_GREENASIA_FF=y
CONFIG_HID_SMARTJOYPLUS=y
# CONFIG_SMARTJOYPLUS_FF is not set
CONFIG_HID_TIVO=y
CONFIG_HID_TOPSEED=y
CONFIG_HID_THINGM=y
CONFIG_HID_THRUSTMASTER=y
# CONFIG_THRUSTMASTER_FF is not set
# CONFIG_HID_WACOM is not set
CONFIG_HID_WIIMOTE=y
CONFIG_HID_XINMO=y
# CONFIG_HID_ZEROPLUS is not set
CONFIG_HID_ZYDACRON=y
CONFIG_HID_SENSOR_HUB=y

#
# USB HID support
#
# CONFIG_USB_HID is not set
CONFIG_HID_PID=y

#
# I2C HID support
#
# CONFIG_I2C_HID is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_COMMON=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEFAULT_PERSIST=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
CONFIG_USB_MON=y
CONFIG_USB_WUSB_CBAF=y
# CONFIG_USB_WUSB_CBAF_DEBUG is not set

#
# USB Host Controller Drivers
#
CONFIG_USB_C67X00_HCD=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
# CONFIG_USB_EHCI_TT_NEWSCHED is not set
CONFIG_USB_EHCI_PCI=y
# CONFIG_USB_EHCI_HCD_PLATFORM is not set
CONFIG_USB_OXU210HP_HCD=y
CONFIG_USB_ISP116X_HCD=y
CONFIG_USB_ISP1760_HCD=y
# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_FUSBH200_HCD=y
CONFIG_USB_FOTG210_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_HCD_PCI=y
CONFIG_USB_OHCI_HCD_PLATFORM=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
CONFIG_USB_RENESAS_USBHS_HCD=y
CONFIG_USB_HCD_TEST_MODE=y
CONFIG_USB_MUSB_HDRC=y
# CONFIG_USB_MUSB_HOST is not set
# CONFIG_USB_MUSB_GADGET is not set
CONFIG_USB_MUSB_DUAL_ROLE=y
CONFIG_USB_MUSB_TUSB6010=y
# CONFIG_USB_MUSB_DSPS is not set
# CONFIG_USB_MUSB_UX500 is not set
CONFIG_MUSB_PIO_ONLY=y
CONFIG_USB_RENESAS_USBHS=y

#
# USB Device Class drivers
#
CONFIG_USB_ACM=y
CONFIG_USB_PRINTER=y
CONFIG_USB_WDM=y
# CONFIG_USB_TMC is not set

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
CONFIG_USB_STORAGE_DEBUG=y
CONFIG_USB_STORAGE_REALTEK=y
# CONFIG_REALTEK_AUTOPM is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
CONFIG_USB_STORAGE_FREECOM=y
CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_USBAT=y
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
CONFIG_USB_STORAGE_ALAUDA=y
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_STORAGE_ENE_UB6250=y

#
# USB Imaging devices
#
CONFIG_USB_MDC800=y
CONFIG_USB_MICROTEK=y
# CONFIG_USB_DWC3 is not set
CONFIG_USB_CHIPIDEA=y
# CONFIG_USB_CHIPIDEA_UDC is not set
# CONFIG_USB_CHIPIDEA_HOST is not set
CONFIG_USB_CHIPIDEA_DEBUG=y

#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
CONFIG_USB_EMI62=y
CONFIG_USB_EMI26=y
CONFIG_USB_ADUTUX=y
CONFIG_USB_SEVSEG=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
CONFIG_USB_LCD=y
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
CONFIG_USB_CYTHERM=y
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
CONFIG_USB_APPLEDISPLAY=y
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
CONFIG_USB_IOWARRIOR=y
CONFIG_USB_TEST=y
# CONFIG_USB_EHSET_TEST_FIXTURE is not set
CONFIG_USB_ISIGHTFW=y
CONFIG_USB_YUREX=y
CONFIG_USB_EZUSB_FX2=y
CONFIG_USB_HSIC_USB3503=y
# CONFIG_USB_ATM is not set

#
# USB Physical Layer drivers
#
CONFIG_USB_PHY=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_OMAP_CONTROL_USB=y
CONFIG_OMAP_USB3=y
CONFIG_AM335X_CONTROL_USB=y
CONFIG_AM335X_PHY_USB=y
# CONFIG_SAMSUNG_USB2PHY is not set
# CONFIG_SAMSUNG_USB3PHY is not set
# CONFIG_USB_GPIO_VBUS is not set
CONFIG_USB_ISP1301=y
CONFIG_USB_RCAR_PHY=y
CONFIG_USB_GADGET=y
# CONFIG_USB_GADGET_DEBUG is not set
# CONFIG_USB_GADGET_DEBUG_FILES is not set
# CONFIG_USB_GADGET_DEBUG_FS is not set
CONFIG_USB_GADGET_VBUS_DRAW=2
CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2

#
# USB Peripheral Controller
#
CONFIG_USB_FUSB300=y
CONFIG_USB_FOTG210_UDC=y
# CONFIG_USB_R8A66597 is not set
CONFIG_USB_RENESAS_USBHS_UDC=y
# CONFIG_USB_PXA27X is not set
CONFIG_USB_MV_UDC=y
CONFIG_USB_MV_U3D=y
# CONFIG_USB_M66592 is not set
# CONFIG_USB_AMD5536UDC is not set
# CONFIG_USB_NET2272 is not set
# CONFIG_USB_NET2280 is not set
# CONFIG_USB_GOKU is not set
# CONFIG_USB_EG20T is not set
# CONFIG_USB_DUMMY_HCD is not set
CONFIG_USB_LIBCOMPOSITE=y
# CONFIG_USB_CONFIGFS is not set
# CONFIG_USB_ZERO is not set
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_ETH is not set
# CONFIG_USB_G_NCM is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_USB_FUNCTIONFS is not set
# CONFIG_USB_MASS_STORAGE is not set
# CONFIG_USB_GADGET_TARGET is not set
# CONFIG_USB_G_SERIAL is not set
CONFIG_USB_MIDI_GADGET=y
# CONFIG_USB_G_PRINTER is not set
# CONFIG_USB_CDC_COMPOSITE is not set
# CONFIG_USB_G_NOKIA is not set
# CONFIG_USB_G_ACM_MS is not set
# CONFIG_USB_G_MULTI is not set
# CONFIG_USB_G_HID is not set
# CONFIG_USB_G_DBGP is not set
# CONFIG_UWB is not set
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
CONFIG_MMC_UNSAFE_RESUME=y
# CONFIG_MMC_CLKGATE is not set

#
# MMC/SD/SDIO Card Drivers
#
CONFIG_MMC_BLOCK=y
CONFIG_MMC_BLOCK_MINORS=8
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_SDIO_UART is not set
# CONFIG_MMC_TEST is not set

#
# MMC/SD/SDIO Host Controller Drivers
#
CONFIG_MMC_SDHCI=y
# CONFIG_MMC_SDHCI_PCI is not set
# CONFIG_MMC_SDHCI_ACPI is not set
# CONFIG_MMC_SDHCI_PLTFM is not set
# CONFIG_MMC_OMAP_HS is not set
CONFIG_MMC_WBSD=y
# CONFIG_MMC_TIFM_SD is not set
# CONFIG_MMC_SDRICOH_CS is not set
# CONFIG_MMC_CB710 is not set
# CONFIG_MMC_VIA_SDMMC is not set
# CONFIG_MMC_VUB300 is not set
CONFIG_MMC_USHC=y
CONFIG_MEMSTICK=y
CONFIG_MEMSTICK_DEBUG=y

#
# MemoryStick drivers
#
# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
CONFIG_MSPRO_BLOCK=y
# CONFIG_MS_BLOCK is not set

#
# MemoryStick Host Controller Drivers
#
# CONFIG_MEMSTICK_TIFM_MS is not set
# CONFIG_MEMSTICK_JMICRON_38X is not set
# CONFIG_MEMSTICK_R592 is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y

#
# LED drivers
#
# CONFIG_LEDS_88PM860X is not set
CONFIG_LEDS_LM3530=y
# CONFIG_LEDS_LM3533 is not set
# CONFIG_LEDS_LM3642 is not set
# CONFIG_LEDS_PCA9532 is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_LP3944=y
CONFIG_LEDS_LP55XX_COMMON=y
# CONFIG_LEDS_LP5521 is not set
CONFIG_LEDS_LP5523=y
CONFIG_LEDS_LP5562=y
CONFIG_LEDS_LP8501=y
CONFIG_LEDS_CLEVO_MAIL=y
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_PCA963X is not set
# CONFIG_LEDS_DA903X is not set
# CONFIG_LEDS_DA9052 is not set
# CONFIG_LEDS_DAC124S085 is not set
# CONFIG_LEDS_PWM is not set
CONFIG_LEDS_REGULATOR=y
# CONFIG_LEDS_BD2802 is not set
# CONFIG_LEDS_INTEL_SS4200 is not set
CONFIG_LEDS_LT3593=y
CONFIG_LEDS_ADP5520=y
CONFIG_LEDS_MC13783=y
CONFIG_LEDS_TCA6507=y
CONFIG_LEDS_MAX8997=y
CONFIG_LEDS_LM355x=y
CONFIG_LEDS_OT200=y
CONFIG_LEDS_BLINKM=y

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
# CONFIG_LEDS_TRIGGER_TIMER is not set
# CONFIG_LEDS_TRIGGER_ONESHOT is not set
# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_BACKLIGHT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_DEFAULT_ON=y

#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_LEDS_TRIGGER_TRANSIENT=y
CONFIG_LEDS_TRIGGER_CAMERA=y
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
# CONFIG_EDAC is not set
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
CONFIG_UIO=y
# CONFIG_UIO_CIF is not set
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_UIO_DMEM_GENIRQ is not set
# CONFIG_UIO_AEC is not set
# CONFIG_UIO_SERCOS3 is not set
# CONFIG_UIO_PCI_GENERIC is not set
# CONFIG_UIO_NETX is not set
# CONFIG_UIO_MF624 is not set
CONFIG_VIRT_DRIVERS=y
CONFIG_VIRTIO=y

#
# Virtio drivers
#
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_BALLOON is not set
CONFIG_VIRTIO_MMIO=y
# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set

#
# Microsoft Hyper-V guest support
#
# CONFIG_HYPERV is not set
# CONFIG_STAGING is not set
# CONFIG_X86_PLATFORM_DEVICES is not set

#
# Hardware Spinlock drivers
#
CONFIG_CLKSRC_I8253=y
CONFIG_CLKEVT_I8253=y
CONFIG_I8253_LOCK=y
CONFIG_CLKBLD_I8253=y
# CONFIG_MAILBOX is not set
# CONFIG_IOMMU_SUPPORT is not set

#
# Remoteproc drivers
#
CONFIG_REMOTEPROC=y
CONFIG_STE_MODEM_RPROC=y

#
# Rpmsg drivers
#
CONFIG_PM_DEVFREQ=y

#
# DEVFREQ Governors
#
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
CONFIG_DEVFREQ_GOV_PERFORMANCE=y
# CONFIG_DEVFREQ_GOV_POWERSAVE is not set
CONFIG_DEVFREQ_GOV_USERSPACE=y

#
# DEVFREQ Drivers
#
CONFIG_EXTCON=y

#
# Extcon Device Drivers
#
CONFIG_OF_EXTCON=y
CONFIG_EXTCON_GPIO=y
CONFIG_EXTCON_MAX8997=y
CONFIG_EXTCON_ARIZONA=y
# CONFIG_MEMORY is not set
# CONFIG_IIO is not set
# CONFIG_NTB is not set
# CONFIG_VME_BUS is not set
CONFIG_PWM=y
CONFIG_PWM_SYSFS=y
CONFIG_PWM_PCA9685=y
# CONFIG_PWM_TWL is not set
# CONFIG_PWM_TWL_LED is not set
CONFIG_IRQCHIP=y
# CONFIG_IPACK_BUS is not set
CONFIG_RESET_CONTROLLER=y
CONFIG_FMC=y
# CONFIG_FMC_FAKEDEV is not set
# CONFIG_FMC_TRIVIAL is not set
CONFIG_FMC_WRITE_EEPROM=y
CONFIG_FMC_CHARDEV=y

#
# Firmware Drivers
#
CONFIG_EDD=y
CONFIG_EDD_OFF=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_DELL_RBU=y
CONFIG_DCDBAS=y
# CONFIG_DMIID is not set
CONFIG_DMI_SYSFS=y
# CONFIG_ISCSI_IBFT_FIND is not set
# CONFIG_GOOGLE_FIRMWARE is not set

#
# File systems
#
CONFIG_DCACHE_WORD_ACCESS=y
# CONFIG_EXT2_FS is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_XATTR=y
CONFIG_EXT3_FS_POSIX_ACL=y
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_USE_FOR_EXT23=y
CONFIG_EXT4_FS_POSIX_ACL=y
# CONFIG_EXT4_FS_SECURITY is not set
# CONFIG_EXT4_DEBUG is not set
CONFIG_JBD=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2=y
CONFIG_JBD2_DEBUG=y
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
CONFIG_REISERFS_CHECK=y
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_REISERFS_FS_XATTR is not set
# CONFIG_JFS_FS is not set
CONFIG_XFS_FS=y
CONFIG_XFS_QUOTA=y
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
CONFIG_XFS_DEBUG=y
CONFIG_GFS2_FS=y
CONFIG_OCFS2_FS=y
CONFIG_OCFS2_FS_O2CB=y
# CONFIG_OCFS2_FS_STATS is not set
# CONFIG_OCFS2_DEBUG_MASKLOG is not set
# CONFIG_OCFS2_DEBUG_FS is not set
# CONFIG_BTRFS_FS is not set
# CONFIG_NILFS2_FS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_EXPORTFS=y
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
CONFIG_INOTIFY_USER=y
# CONFIG_FANOTIFY is not set
CONFIG_QUOTA=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
# CONFIG_PRINT_QUOTA_WARNING is not set
CONFIG_QUOTA_DEBUG=y
CONFIG_QUOTA_TREE=y
# CONFIG_QFMT_V1 is not set
CONFIG_QFMT_V2=y
CONFIG_QUOTACTL=y
# CONFIG_AUTOFS4_FS is not set
CONFIG_FUSE_FS=y
CONFIG_CUSE=y

#
# Caches
#
CONFIG_FSCACHE=y
# CONFIG_FSCACHE_STATS is not set
CONFIG_FSCACHE_HISTOGRAM=y
# CONFIG_FSCACHE_DEBUG is not set
# CONFIG_FSCACHE_OBJECT_LIST is not set
CONFIG_CACHEFILES=y
CONFIG_CACHEFILES_DEBUG=y
CONFIG_CACHEFILES_HISTOGRAM=y

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
CONFIG_ZISOFS=y
CONFIG_UDF_FS=y
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
CONFIG_NTFS_FS=y
CONFIG_NTFS_DEBUG=y
CONFIG_NTFS_RW=y

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_CONFIGFS_FS=y
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
CONFIG_AFFS_FS=y
CONFIG_ECRYPT_FS=y
# CONFIG_ECRYPT_FS_MESSAGING is not set
CONFIG_HFS_FS=y
# CONFIG_HFSPLUS_FS is not set
CONFIG_BEFS_FS=y
# CONFIG_BEFS_DEBUG is not set
CONFIG_BFS_FS=y
CONFIG_EFS_FS=y
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
CONFIG_JFFS2_FS_XATTR=y
# CONFIG_JFFS2_FS_POSIX_ACL is not set
CONFIG_JFFS2_FS_SECURITY=y
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
# CONFIG_JFFS2_RTIME is not set
# CONFIG_JFFS2_RUBIN is not set
# CONFIG_JFFS2_CMODE_NONE is not set
CONFIG_JFFS2_CMODE_PRIORITY=y
# CONFIG_JFFS2_CMODE_SIZE is not set
# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
CONFIG_UBIFS_FS=y
# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_ZLIB=y
# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_XATTR is not set
CONFIG_SQUASHFS_ZLIB=y
# CONFIG_SQUASHFS_LZO is not set
# CONFIG_SQUASHFS_XZ is not set
# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
# CONFIG_SQUASHFS_EMBEDDED is not set
CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_OMFS_FS=y
CONFIG_HPFS_FS=y
CONFIG_QNX4FS_FS=y
CONFIG_QNX6FS_FS=y
# CONFIG_QNX6FS_DEBUG is not set
CONFIG_ROMFS_FS=y
# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
CONFIG_ROMFS_BACKED_BY_MTD=y
# CONFIG_ROMFS_BACKED_BY_BOTH is not set
CONFIG_ROMFS_ON_MTD=y
# CONFIG_PSTORE is not set
CONFIG_SYSV_FS=y
CONFIG_UFS_FS=y
CONFIG_UFS_FS_WRITE=y
CONFIG_UFS_DEBUG=y
# CONFIG_F2FS_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
CONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
CONFIG_NLS_CODEPAGE_857=y
CONFIG_NLS_CODEPAGE_860=y
CONFIG_NLS_CODEPAGE_861=y
# CONFIG_NLS_CODEPAGE_862 is not set
CONFIG_NLS_CODEPAGE_863=y
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
CONFIG_NLS_CODEPAGE_866=y
# CONFIG_NLS_CODEPAGE_869 is not set
CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_CODEPAGE_950=y
CONFIG_NLS_CODEPAGE_932=y
# CONFIG_NLS_CODEPAGE_949 is not set
CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_ISO8859_8=y
# CONFIG_NLS_CODEPAGE_1250 is not set
CONFIG_NLS_CODEPAGE_1251=y
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
CONFIG_NLS_ISO8859_9=y
CONFIG_NLS_ISO8859_13=y
CONFIG_NLS_ISO8859_14=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_MAC_ROMAN=y
# CONFIG_NLS_MAC_CELTIC is not set
CONFIG_NLS_MAC_CENTEURO=y
CONFIG_NLS_MAC_CROATIAN=y
# CONFIG_NLS_MAC_CYRILLIC is not set
# CONFIG_NLS_MAC_GAELIC is not set
CONFIG_NLS_MAC_GREEK=y
# CONFIG_NLS_MAC_ICELAND is not set
# CONFIG_NLS_MAC_INUIT is not set
# CONFIG_NLS_MAC_ROMANIAN is not set
CONFIG_NLS_MAC_TURKISH=y
CONFIG_NLS_UTF8=y

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y

#
# printk and dmesg options
#
CONFIG_PRINTK_TIME=y
CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
# CONFIG_BOOT_PRINTK_DELAY is not set
CONFIG_DYNAMIC_DEBUG=y

#
# Compile-time checks and compiler options
#
# CONFIG_DEBUG_INFO is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=1024
CONFIG_STRIP_ASM_SYMS=y
# CONFIG_READABLE_ASM is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_FRAME_POINTER=y
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y

#
# Memory Debugging
#
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_OBJECTS is not set
CONFIG_SLUB_DEBUG_ON=y
CONFIG_SLUB_STATS=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_VIRTUAL is not set
CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_HIGHMEM is not set
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
CONFIG_HAVE_ARCH_KMEMCHECK=y
# CONFIG_DEBUG_SHIRQ is not set

#
# Debug Lockups and Hangs
#
# CONFIG_LOCKUP_DETECTOR is not set
# CONFIG_DETECT_HUNG_TASK is not set
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set

#
# Lock Debugging (spinlocks, mutexes, etc...)
#
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_ATOMIC_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_KOBJECT_RELEASE is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_DEBUG_CREDENTIALS is not set

#
# RCU Debugging
#
# CONFIG_SPARSE_RCU_POINTER is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_TRACE is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_USER_STACKTRACE_SUPPORT=y
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_TRACER_MAX_TRACE=y
CONFIG_TRACE_CLOCK=y
CONFIG_RING_BUFFER=y
CONFIG_EVENT_TRACING=y
CONFIG_CONTEXT_SWITCH_TRACER=y
CONFIG_TRACING=y
CONFIG_GENERIC_TRACER=y
CONFIG_TRACING_SUPPORT=y
CONFIG_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
# CONFIG_IRQSOFF_TRACER is not set
CONFIG_SCHED_TRACER=y
CONFIG_FTRACE_SYSCALLS=y
CONFIG_TRACER_SNAPSHOT=y
# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
CONFIG_TRACE_BRANCH_PROFILING=y
# CONFIG_BRANCH_PROFILE_NONE is not set
CONFIG_PROFILE_ANNOTATED_BRANCHES=y
# CONFIG_PROFILE_ALL_BRANCHES is not set
CONFIG_TRACING_BRANCHES=y
CONFIG_BRANCH_TRACER=y
CONFIG_STACK_TRACER=y
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_UPROBE_EVENT=y
CONFIG_PROBE_EVENTS=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_FTRACE_MCOUNT_RECORD=y
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_MMIOTRACE is not set
CONFIG_RING_BUFFER_BENCHMARK=y
# CONFIG_RING_BUFFER_STARTUP_TEST is not set

#
# Runtime Testing
#
CONFIG_LKDTM=y
# CONFIG_TEST_LIST_SORT is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_RBTREE_TEST is not set
# CONFIG_ATOMIC64_SELFTEST is not set
CONFIG_TEST_STRING_HELPERS=y
# CONFIG_TEST_KSTRTOX is not set
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
CONFIG_BUILD_DOCSRC=y
# CONFIG_DMA_API_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_STRICT_DEVMEM=y
CONFIG_X86_VERBOSE_BOOTUP=y
CONFIG_EARLY_PRINTK=y
# CONFIG_EARLY_PRINTK_DBGP is not set
# CONFIG_X86_PTDUMP is not set
CONFIG_DEBUG_RODATA=y
CONFIG_DEBUG_RODATA_TEST=y
CONFIG_DOUBLEFAULT=y
# CONFIG_DEBUG_TLBFLUSH is not set
CONFIG_IOMMU_STRESS=y
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
CONFIG_IO_DELAY_TYPE_0X80=0
CONFIG_IO_DELAY_TYPE_0XED=1
CONFIG_IO_DELAY_TYPE_UDELAY=2
CONFIG_IO_DELAY_TYPE_NONE=3
# CONFIG_IO_DELAY_0X80 is not set
CONFIG_IO_DELAY_0XED=y
# CONFIG_IO_DELAY_UDELAY is not set
# CONFIG_IO_DELAY_NONE is not set
CONFIG_DEFAULT_IO_DELAY_TYPE=1
# CONFIG_DEBUG_BOOT_PARAMS is not set
# CONFIG_CPA_DEBUG is not set
# CONFIG_OPTIMIZE_INLINING is not set
# CONFIG_DEBUG_NMI_SELFTEST is not set
# CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set

#
# Security options
#
CONFIG_KEYS=y
CONFIG_ENCRYPTED_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY_DMESG_RESTRICT is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
CONFIG_DEFAULT_SECURITY_DAC=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_PCOMP=y
CONFIG_CRYPTO_PCOMP2=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_USER is not set
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_GF128MUL=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_WORKQUEUE=y
CONFIG_CRYPTO_CRYPTD=y
CONFIG_CRYPTO_AUTHENC=y
CONFIG_CRYPTO_ABLK_HELPER_X86=y

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_SEQIV=y

#
# Block modes
#
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_CTS=y
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XTS=y

#
# Hash modes
#
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
# CONFIG_CRYPTO_VMAC is not set

#
# Digest
#
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_CRC32C_INTEL=y
CONFIG_CRYPTO_CRC32=y
# CONFIG_CRYPTO_CRC32_PCLMUL is not set
CONFIG_CRYPTO_CRCT10DIF=y
CONFIG_CRYPTO_GHASH=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_RMD128=y
CONFIG_CRYPTO_RMD160=y
CONFIG_CRYPTO_RMD256=y
CONFIG_CRYPTO_RMD320=y
# CONFIG_CRYPTO_SHA1 is not set
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_TGR192=y
# CONFIG_CRYPTO_WP512 is not set

#
# Ciphers
#
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_AES_586=y
CONFIG_CRYPTO_AES_NI_INTEL=y
# CONFIG_CRYPTO_ANUBIS is not set
CONFIG_CRYPTO_ARC4=y
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_CAST_COMMON=y
CONFIG_CRYPTO_CAST5=y
CONFIG_CRYPTO_CAST6=y
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_FCRYPT=y
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
CONFIG_CRYPTO_SALSA20_586=y
# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_SERPENT=y
# CONFIG_CRYPTO_SERPENT_SSE2_586 is not set
# CONFIG_CRYPTO_TEA is not set
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y
CONFIG_CRYPTO_TWOFISH_586=y

#
# Compression
#
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_ZLIB=y
CONFIG_CRYPTO_LZO=y
# CONFIG_CRYPTO_LZ4 is not set
CONFIG_CRYPTO_LZ4HC=y

#
# Random Number Generation
#
CONFIG_CRYPTO_ANSI_CPRNG=y
CONFIG_CRYPTO_USER_API=y
CONFIG_CRYPTO_USER_API_HASH=y
# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
# CONFIG_CRYPTO_HW is not set
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
CONFIG_PUBLIC_KEY_ALGO_RSA=y
CONFIG_X509_CERTIFICATE_PARSER=y
CONFIG_HAVE_KVM=y
CONFIG_VIRTUALIZATION=y
CONFIG_LGUEST=y
CONFIG_BINARY_PRINTF=y

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GENERIC_NET_UTILS=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_IO=y
CONFIG_PERCPU_RWSEM=y
CONFIG_CRC_CCITT=y
CONFIG_CRC16=y
CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC32=y
CONFIG_CRC32_SELFTEST=y
# CONFIG_CRC32_SLICEBY8 is not set
# CONFIG_CRC32_SLICEBY4 is not set
CONFIG_CRC32_SARWATE=y
# CONFIG_CRC32_BIT is not set
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
CONFIG_CRC8=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_LZ4HC_COMPRESS=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_XZ_DEC=y
CONFIG_XZ_DEC_X86=y
CONFIG_XZ_DEC_POWERPC=y
# CONFIG_XZ_DEC_IA64 is not set
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_ARMTHUMB=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_BCJ=y
# CONFIG_XZ_DEC_TEST is not set
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_BCH=y
CONFIG_BCH_CONST_PARAMS=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_CHECK_SIGNATURE=y
CONFIG_DQL=y
CONFIG_NLATTR=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_AVERAGE is not set
CONFIG_CLZ_TAB=y
CONFIG_CORDIC=y
# CONFIG_DDR is not set
CONFIG_MPILIB=y
CONFIG_OID_REGISTRY=y
CONFIG_FONT_SUPPORT=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y

From matthieu.castet at parrot.com  Wed Oct  9 03:28:55 2013
From: matthieu.castet at parrot.com (Matthieu CASTET)
Date: Wed, 9 Oct 2013 09:28:55 +0200
Subject: Grow UBI device?
In-Reply-To: <20131008192846.A25E7380A65@gemini.denx.de>
References: <20131008192846.A25E7380A65@gemini.denx.de>
Message-ID: <20131009092855.77d311fd@parrot.com>

Le Tue, 8 Oct 2013 20:28:46 +0100,
Wolfgang Denk <wd at denx.de> a ?crit :

> so I can keep an existing MTD partition with a JFFS2
> file system. After copying the data from JFFS2 to a UBIFS volume, I
> would like to free and reuse the space of this JFFS2 partition.
> 
> Is there a way to "grow" the existing UBI device so that it now also
> covers the rest of the NAND chip?  Or is my only option to create a
> second UBI device?
I don't remeber exactly but I think UBI (without fastmap) doesn't know
the size of the mtd partition.
The scan scan what you give to it.

A way to "grow an UBI device could be to append (before or after)
flash formated with ubi format (with --no-volume-table and the correct
--image-seq= and same other param).
If you give erased flash may be the linux driver will format it.



Matthieu


From dwmw2 at infradead.org  Wed Oct  9 04:16:17 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Wed, 09 Oct 2013 09:16:17 +0100
Subject: [GIT PULL] MTD fixes for 3.12-rc
In-Reply-To: <1381284622-24286-1-git-send-email-computersforpeace@gmail.com>
References: <1381284622-24286-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1381306577.9617.15.camel@shinybook.infradead.org>

On Tue, 2013-10-08 at 19:10 -0700, Brian Norris wrote:
> Hi Linus!
> 
> David Woodhouse and I have queued up a few MTD fixes for 3.12. As David seems
> to be MIA again, I am sending the following pull request with his permission.

Not entirely MIA; just still catching up with work and sleep after being
in Portland last week. I prefer to be properly awake before sending
Linus pull requests; it saves getting shouted at :)

The pull request looks good; thanks Brian.

You should probably be signing your tags. Even if your key isn't in the
strong set yet, at least they would consistently be signed with the
*same* key.

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/0b1267f5/attachment.bin>

From ricard.wanderlof at axis.com  Wed Oct  9 04:46:40 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Wed, 9 Oct 2013 10:46:40 +0200
Subject: Grow UBI device?
In-Reply-To: <20131008192846.A25E7380A65@gemini.denx.de>
References: <20131008192846.A25E7380A65@gemini.denx.de>
Message-ID: <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>


On Tue, 8 Oct 2013, Wolfgang Denk wrote:

> Hi,
>
> I'm looking for a clever way to migrate devices (in the field) from
> JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
> device (which covers the whole NAND chip) with several volumes used
> with UBIFS.  Unfortunately I must keep some of the existing data.
>
> It would be nice if I could start with a UBI device that is smaller
> than the NAND, so I can keep an existing MTD partition with a JFFS2
> file system. After copying the data from JFFS2 to a UBIFS volume, I
> would like to free and reuse the space of this JFFS2 partition.
>
> Is there a way to "grow" the existing UBI device so that it now also 
> covers the rest of the NAND chip?  Or is my only option to create a 
> second UBI device?

UBI devices are 'attached' to existing mtd partitions. So to grow a UBI 
device, you need to detach it from the partition, re-partition the flash 
(and I'm not sure if this step is even possible as it involves 
unregistering existing mtd partitions), then attach a UBI device to the a 
new partition.

Come to think of it, I'm not sure that would work anyway, as the 
resulting, new, enlarged partition would partly contain UBI data and 
partly old jffs2 data. I'm not sure what UBI does when it encounters 
incorrect data, if it just erases the relevant blocks and formats them for 
its own use, or if it barfs completely and just bails out complaining that 
the partition does not contain UBI data. If the relevant blocks were 
erased, then I think UBI would simply concede that the a previous erase 
attempt had been prematurely aborted, and re-erase the blocks and write 
its headers, so perhaps that is something to try. At any rate it involves 
at least some mild trickery (erase the blocks that previously contained 
jffs2 data).

It's probably easier to create a new UBI device by attaching it to the 
partition previously used by jffs2, after erasing it, but multiple UBI 
devices across a flash partly defeats the purpose of wear-leveling which 
UBI provides.

/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 b32955 at freescale.com  Wed Oct  9 05:00:12 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 9 Oct 2013 17:00:12 +0800
Subject: [PATCH] ubi: attach: do not return -EINVAL if the
 mtd->numeraseregions is 1
In-Reply-To: <1379470659-12158-1-git-send-email-b32955@freescale.com>
References: <1379470659-12158-1-git-send-email-b32955@freescale.com>
Message-ID: <52551B1C.4080608@freescale.com>

? 2013?09?18? 10:17, Huang Shijie ??:
> If the master mtd does not have any slave mtd partitions,
> and its numeraseregions is one(only has one erease block), and
> we attach the master mtd with : ubiattach -m 0 -d 0
>
> We will meet the error:
> -------------------------------------------------------
> root at freescale ~$ ubiattach /dev/ubi_ctrl -m 0 -d 0
> UBI: attaching mtd0 to ubi0
> UBI error: io_init: multiple regions, not implemented
> ubiattach: error!: cannot attach mtd0
>            error 22 (Invalid argument)
> -------------------------------------------------------
>
> In fact, if there is only one "erase block", we should not
> prevent the attach.
>
> This patch fixes it.
>
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
>  drivers/mtd/ubi/build.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
> index a561335..006f98a 100644
> --- a/drivers/mtd/ubi/build.c
> +++ b/drivers/mtd/ubi/build.c
> @@ -638,7 +638,7 @@ static int io_init(struct ubi_device *ubi, int max_beb_per1024)
>  	dbg_gen("sizeof(struct ubi_ainf_peb) %zu", sizeof(struct ubi_ainf_peb));
>  	dbg_gen("sizeof(struct ubi_wl_entry) %zu", sizeof(struct ubi_wl_entry));
>  
> -	if (ubi->mtd->numeraseregions != 0) {
> +	if (ubi->mtd->numeraseregions > 1) {
>  		/*
>  		 * Some flashes have several erase regions. Different regions
>  		 * may have different eraseblock size and other
Hi Artem:
could you please check this patch?


thanks
Huang Shijie



From marex at denx.de  Wed Oct  9 06:14:02 2013
From: marex at denx.de (Marek Vasut)
Date: Wed, 9 Oct 2013 12:14:02 +0200
Subject: N25Q256A 13E40
In-Reply-To: <CAN8TOE_C+uU+JXn2OJ_5y6DbvxQXTQK7emEqoxXkCHkCzSQ13g@mail.gmail.com>
References: <201310071824.01028.marex@denx.de>
 <CAN8TOE_C+uU+JXn2OJ_5y6DbvxQXTQK7emEqoxXkCHkCzSQ13g@mail.gmail.com>
Message-ID: <201310091214.02740.marex@denx.de>

Hi Brian,

> On Mon, Oct 7, 2013 at 9:24 AM, Marek Vasut <marex at denx.de> wrote:
> > Let's talk about our favourite chip :) I just got my hands on N25Q256A .
> > Since there was quite a flurry of patches for this and similar chips and
> > I got it working on a different chip with exactly the same IDs and type,
> > I'd would expect linux to work with this one too. Guess what ... ;-)
> > 
> > This particular incarnation of N25Q256A completely ignores the 4-byte
> > ERASE (0xdc) command. Apparently, if I look closely, it's N25Q256A 13E40
> > variant and seeing the Note #14 (datasheet page 30 / below Table 18.
> > Command set), quoting:
> > 
> > 14.This command is only for part numbers N25Q256A83ESF40x and
> > N25Q256A83E1240x.
> 
> This note also applies to PAGE_PROGRAM_4B (0x12) as well, right?

Yeah, both ERASE_4B and PP_4B or whatever they're called there. Interestingly 
enough, READ_4B works ;-/

> > they are not supported on this part. Someone surely did some hard
> > thinking inventing such a crappy part.
> 
> Yeah, we were already seeing this kind of inconsistency. I recall
> Micron saying that they tried to make the N25Q256A83xx... parts
> compatible with Macronix. Why they didn't just do that for the whole
> product line is anybody's guess...
> 
> > I can surely cook a patch, but I wonder what
> > direction we should take here. We can switch this chip into 4-byte mode
> > by 0xb7/0xe9 opcodes, which would in turn break BootROMs which depend on
> > the SPI NOR to be in 3-byte mode upon reboot. We can program the BAR
> > register before erase, which will do the same.
> > 
> > Sigh, if you have any idea, that'd be nice to hear.
> 
> Is there any way to differentiate the N25Q256Axx... flavors by ID or
> similar? (I believe I know the answer to this already, and it's not
> the answer I want.)

You can look at the top of the chip and read the label on top of it ;-/ But 
software-wise, no, there's no way to tell the crap ones from the not-crap ones.

> I don't think we want to start using the BAR. I think the 0xb7/0xe9
> opcodes are best (if we really have to...), since we already support
> them, and we never really *guarantee* that m25p80.c will leave the
> flash in 3-byte mode. It was just an added bonus that we are able to
> be mode-less on some flash.

Good point.

> [Now that I went back to look at some more code:] Wait, but we don't
> even try to use the 4-byte dedicated commands like 0xdc on Micron
> flash, so why are you having this problem? The code currently stands
> as:

The JEDEC_MFR for this flash Micron N25Q256A is CFI_MFR_ST (I wonder why).

>   if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
>           /* Dedicated 4-byte command set */
>           ...
> 
> They are only used on Spansion. IIRC, I wrote it this way specifically
> because Micron is so inconsistent, at least on their current
> generation (they're fixing that for the future, I think, but that
> doesn't help us of course). And I haven't had a chance to look at
> others too closely to judge them on this.

Spansion is good indeed, they always worked as they should have and were 
consistent.

Best regards,
Marek Vasut


From pekon at ti.com  Wed Oct  9 07:28:52 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 9 Oct 2013 11:28:52 +0000
Subject: Grow UBI device?
In-Reply-To: <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>

> From: Ricard Wanderlof
> > On Tue, 8 Oct 2013, Wolfgang Denk wrote:
> > I'm looking for a clever way to migrate devices (in the field) from
> > JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
> > device (which covers the whole NAND chip) with several volumes used
> > with UBIFS.  Unfortunately I must keep some of the existing data.
> >
> > It would be nice if I could start with a UBI device that is smaller
> > than the NAND, so I can keep an existing MTD partition with a JFFS2
> > file system. After copying the data from JFFS2 to a UBIFS volume, I
> > would like to free and reuse the space of this JFFS2 partition.
> >
That seems to be a nice move, but where would you copy the existing
JFFS2 data ?
(a) In memory, then there is threat of losing the data due to
  power-failure, and you should have enough RAM.
(b) copy to target UBIFS volume/partition. So assumption is that target
  UBI volume has enough space and is writable.
I'm assuming (b) is more workable .. 


> > Is there a way to "grow" the existing UBI device so that it now also
> > covers the rest of the NAND chip?  Or is my only option to create a
> > second UBI device?
> 
> UBI devices are 'attached' to existing mtd partitions. So to grow a UBI
> device, you need to detach it from the partition, re-partition the flash
> (and I'm not sure if this step is even possible as it involves
> unregistering existing mtd partitions), then attach a UBI device to the a
> new partition.
> 
Yes, currently registering and de-registering of MTD partitions are
done as part of nand_probe() and nand_remove().
If we do on-the-fly registering / de-registering of MTD device, then we
also need to tweak the mtd partition information, which will change
- partition base offset and 
- shift masks (to calculate offset within the partition)
which is ok, because they are not used by controller drivers directly.


> Come to think of it, I'm not sure that would work anyway, as the
> resulting, new, enlarged partition would partly contain UBI data and
> partly old jffs2 data. I'm not sure what UBI does when it encounters
> incorrect data, if it just erases the relevant blocks and formats them for
> its own use, or if it barfs completely and just bails out complaining that
> the partition does not contain UBI data. If the relevant blocks were
> erased, then I think UBI would simply concede that the a previous erase
> attempt had been prematurely aborted, and re-erase the blocks and write
> its headers, so perhaps that is something to try. At any rate it involves
> at least some mild trickery (erase the blocks that previously contained
> jffs2 data).
> 
Yes, during mounting of UBIFS volumes, UBI checks for erase-header
on first-page of every block. 
- If it's able to find a valid erase-header, with correct image_seq field,
then it attaches it to its pool.
- Otherwise, if the valid erase-header was not found, then it assumes
 then it ubi will try re-erasing it. And add it to its pool of free-blocks.

So, effectively you don't even need to erase the partition to convert
it into UBI volume, you just try attaching it as UBI volume and UBI
should erase it for you. (though flagging some warnings on the way).


> It's probably easier to create a new UBI device by attaching it to the
> partition previously used by jffs2, after erasing it, but multiple UBI
> devices across a flash partly defeats the purpose of wear-leveling which
> UBI provides.
>
True but this is good for on-field devices which are still on JFFS2 and
want to migrate to UBIFS for same reasons. Also, this would help in
other areas like recovery from power-failures.
 

with regards, pekon


From ezequiel.garcia at free-electrons.com  Wed Oct  9 07:48:04 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 9 Oct 2013 08:48:04 -0300
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131009114803.GA31294@localhost>

On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
> As part of my work to support the NAND controllers in Armada 370/XP SoC
> here's a tiny set of patches to replace the currently data buffer allocation
> based in a hardcoded buffer size, into a dynamic scheme.
> 
> We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
> page) and then re-allocate (either with kmalloc or using DMA allocators) using
> the detected page size.
> 
> The first patch is required to perform the initial NAND operations (READID
> and friends) using programmable I/O since the DMA buffers are not ready
> at such early stage.
> 
> The second patch performs to actual dynamic allocation and it's exactly
> the same patch I sent a few weeks ago:
> 
>   http://patchwork.ozlabs.org/patch/275982/
> 
> Daniel: Can you test these two If they look fine we can add them now,
> being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.

Daniel: sorry to bother, any luck testing this?

Brian: do you think the fix might be OK?

I'll include this in my future patchset for pxa3xx-nand, but if these
two look OK, I think we can just merge them now.

Thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From zonque at gmail.com  Wed Oct  9 08:00:28 2013
From: zonque at gmail.com (Daniel Mack)
Date: Wed, 09 Oct 2013 14:00:28 +0200
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <20131009114803.GA31294@localhost>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131009114803.GA31294@localhost>
Message-ID: <5255455C.6060606@gmail.com>

On 09.10.2013 13:48, Ezequiel Garcia wrote:
> On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
>> As part of my work to support the NAND controllers in Armada 370/XP SoC
>> here's a tiny set of patches to replace the currently data buffer allocation
>> based in a hardcoded buffer size, into a dynamic scheme.
>>
>> We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
>> page) and then re-allocate (either with kmalloc or using DMA allocators) using
>> the detected page size.
>>
>> The first patch is required to perform the initial NAND operations (READID
>> and friends) using programmable I/O since the DMA buffers are not ready
>> at such early stage.
>>
>> The second patch performs to actual dynamic allocation and it's exactly
>> the same patch I sent a few weeks ago:
>>
>>   http://patchwork.ozlabs.org/patch/275982/
>>
>> Daniel: Can you test these two If they look fine we can add them now,
>> being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.
> 
> Daniel: sorry to bother, any luck testing this?

Sorry for the delay, got other things to do lately ...

I tested these two patches successfully on my board with both use_dma=0
and =1. Nice :) You can take my

	Tested-by: Daniel Mack <zonque at gmail.com>

I hope I can catch up with my pxa DMA cleanups very soon.


Daniel



From ezequiel.garcia at free-electrons.com  Wed Oct  9 08:02:22 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 9 Oct 2013 09:02:22 -0300
Subject: [PATCH/TRIVIAL] mtd: Use MTD_BLOCK_MAJOR instead of the magic
 number
In-Reply-To: <CAN8TOE-9XRW9QJ7+sSis+Omo0eVAGVHOXD70P4L8FNbLut=9Dg@mail.gmail.com>
References: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAN8TOE-9XRW9QJ7+sSis+Omo0eVAGVHOXD70P4L8FNbLut=9Dg@mail.gmail.com>
Message-ID: <20131009120221.GB31294@localhost>

On Tue, Oct 08, 2013 at 06:15:21PM -0700, Brian Norris wrote:
> On Tue, Oct 8, 2013 at 4:59 PM, Ezequiel Garcia
> <ezequiel.garcia at free-electrons.com> wrote:
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/mtdblock.c    | 2 +-
> >  drivers/mtd/mtdblock_ro.c | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
> > index 2aef5dd..53884cc 100644
> > --- a/drivers/mtd/mtdblock.c
> > +++ b/drivers/mtd/mtdblock.c
> > @@ -373,7 +373,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
> >
> >  static struct mtd_blktrans_ops mtdblock_tr = {
> >         .name           = "mtdblock",
> > -       .major          = 31,
> > +       .major          = MTD_BLOCK_MAJOR,
> >         .part_bits      = 0,
> >         .blksize        = 512,
> >         .open           = mtdblock_open,
> > diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
> > index 92759a9..70d27b4 100644
> > --- a/drivers/mtd/mtdblock_ro.c
> > +++ b/drivers/mtd/mtdblock_ro.c
> > @@ -70,7 +70,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
> >
> >  static struct mtd_blktrans_ops mtdblock_tr = {
> >         .name           = "mtdblock",
> > -       .major          = 31,
> > +       .major          = MTD_BLOCK_MAJOR,
> >         .part_bits      = 0,
> >         .blksize        = 512,
> >         .readsect       = mtdblock_readsect,
> 
> Patch looks good. I'll probably apply soon. Although I might like to
> see the following fixed along with it:
> 
> Why does MTD_BLOCK_MAJOR (and MTD_CHAR_MAJOR) live in
> include/linux/mtd/mtd.h and not include/uapi/linux/major.h?
> 

Ah, nice catch. How about something like this?

diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index f9bfe52..9e1471e 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -24,14 +24,12 @@
 #include <linux/uio.h>
 #include <linux/notifier.h>
 #include <linux/device.h>
+#include <linux/major.h>
 
 #include <mtd/mtd-abi.h>
 
 #include <asm/div64.h>
 
-#define MTD_CHAR_MAJOR 90
-#define MTD_BLOCK_MAJOR 31
-
 #define MTD_ERASE_PENDING	0x01
 #define MTD_ERASING		0x02
 #define MTD_ERASE_SUSPEND	0x04
diff --git a/include/uapi/linux/major.h b/include/uapi/linux/major.h
index 6a8ca98..620252e 100644
--- a/include/uapi/linux/major.h
+++ b/include/uapi/linux/major.h
@@ -54,6 +54,7 @@
 #define ACSI_MAJOR		28
 #define AZTECH_CDROM_MAJOR	29
 #define FB_MAJOR		29   /* /dev/fb* framebuffers */
+#define MTD_BLOCK_MAJOR		31
 #define CM206_CDROM_MAJOR	32
 #define IDE2_MAJOR		33
 #define IDE3_MAJOR		34
@@ -105,6 +106,7 @@
 #define IDE6_MAJOR		88
 #define IDE7_MAJOR		89
 #define IDE8_MAJOR		90
+#define MTD_CHAR_MAJOR		90
 #define IDE9_MAJOR		91
 
 #define DASD_MAJOR		94

--

If you think this is OK, you can take this patch and I'll cook
another one moving MTD_xxx_MAJOR as above.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Wed Oct  9 10:03:13 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 9 Oct 2013 11:03:13 -0300
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <5255455C.6060606@gmail.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131009114803.GA31294@localhost> <5255455C.6060606@gmail.com>
Message-ID: <20131009140312.GC31294@localhost>

On Wed, Oct 09, 2013 at 02:00:28PM +0200, Daniel Mack wrote:
> On 09.10.2013 13:48, Ezequiel Garcia wrote:
> > On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
> >> As part of my work to support the NAND controllers in Armada 370/XP SoC
> >> here's a tiny set of patches to replace the currently data buffer allocation
> >> based in a hardcoded buffer size, into a dynamic scheme.
> >>
> >> We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
> >> page) and then re-allocate (either with kmalloc or using DMA allocators) using
> >> the detected page size.
> >>
> >> The first patch is required to perform the initial NAND operations (READID
> >> and friends) using programmable I/O since the DMA buffers are not ready
> >> at such early stage.
> >>
> >> The second patch performs to actual dynamic allocation and it's exactly
> >> the same patch I sent a few weeks ago:
> >>
> >>   http://patchwork.ozlabs.org/patch/275982/
> >>
> >> Daniel: Can you test these two If they look fine we can add them now,
> >> being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.
> > 
> > Daniel: sorry to bother, any luck testing this?
> 
> Sorry for the delay, got other things to do lately ...
> 

No problem, thanks for testing.

> I tested these two patches successfully on my board with both use_dma=0
> and =1. Nice :) You can take my
> 
> 	Tested-by: Daniel Mack <zonque at gmail.com>
> 

Good news! Brian: all yours :)

> I hope I can catch up with my pxa DMA cleanups very soon.

Indeed. BTW: I had some feedback on why the Armada 370/XP SoC can't
do DMA on the NAND, I'll reply to the older mail with the information.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From wd at denx.de  Wed Oct  9 10:33:18 2013
From: wd at denx.de (Wolfgang Denk)
Date: Wed, 09 Oct 2013 16:33:18 +0200
Subject: Grow UBI device?
In-Reply-To: <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
Message-ID: <20131009143318.7BAEB38049B@gemini.denx.de>

Dear Ricard Wanderlof,

In message <alpine.DEB.2.00.1310091038110.28562 at lnxricardw.se.axis.com> you wrote:
> 
> > Is there a way to "grow" the existing UBI device so that it now also 
> > covers the rest of the NAND chip?  Or is my only option to create a 
> > second UBI device?
> 
> UBI devices are 'attached' to existing mtd partitions. So to grow a UBI 
> device, you need to detach it from the partition, re-partition the flash 
> (and I'm not sure if this step is even possible as it involves 
> unregistering existing mtd partitions), then attach a UBI device to the a 
> new partition.

In my situation it is OK if the update involves a reboot, so it is
certainly possible to change the MTD partition layout.  So this should
not be a problem.

> Come to think of it, I'm not sure that would work anyway, as the 
> resulting, new, enlarged partition would partly contain UBI data and 
> partly old jffs2 data. I'm not sure what UBI does when it encounters 
> incorrect data, if it just erases the relevant blocks and formats them for 
> its own use, or if it barfs completely and just bails out complaining that 
> the partition does not contain UBI data. If the relevant blocks were 
> erased, then I think UBI would simply concede that the a previous erase 
> attempt had been prematurely aborted, and re-erase the blocks and write 
> its headers, so perhaps that is something to try. At any rate it involves 
> at least some mild trickery (erase the blocks that previously contained 
> jffs2 data).

well, this is the exact part where I wanted to know if (1) this is
guaranteed to work (by design), and/or (2) somebody has successfully
done it before.

> It's probably easier to create a new UBI device by attaching it to the 
> partition previously used by jffs2, after erasing it, but multiple UBI 
> devices across a flash partly defeats the purpose of wear-leveling which 
> UBI provides.

Right, and it fragments the device.  That's why I'd like to avoid
that.


Thanks!!

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Doing the good deeds is like the grass in the garden. You  don't  see
its  growth. But, it does by days. Doing the wicked deeds is like the
hone. You don't see its damage. But, it does by days.        - Buddha


From wd at denx.de  Wed Oct  9 11:05:38 2013
From: wd at denx.de (Wolfgang Denk)
Date: Wed, 09 Oct 2013 17:05:38 +0200
Subject: Grow UBI device?
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
Message-ID: <20131009150538.BAD57380432@gemini.denx.de>

Dear "Gupta, Pekon",

In message <20980858CB6D3A4BAE95CA194937D5E73EA20350 at DBDE04.ent.ti.com> you wrote:
>
> > > It would be nice if I could start with a UBI device that is smaller
> > > than the NAND, so I can keep an existing MTD partition with a JFFS2
> > > file system. After copying the data from JFFS2 to a UBIFS volume, I
> > > would like to free and reuse the space of this JFFS2 partition.
> > >
> That seems to be a nice move, but where would you copy the existing
> JFFS2 data ?

Well, I wrote: "copy[...] the data from JFFS2 to a UBIFS volume".

> (a) In memory, then there is threat of losing the data due to
>   power-failure, and you should have enough RAM.
> (b) copy to target UBIFS volume/partition. So assumption is that target
>   UBI volume has enough space and is writable.
> I'm assuming (b) is more workable .. 

...which is what I'm after.

> > Come to think of it, I'm not sure that would work anyway, as the
> > resulting, new, enlarged partition would partly contain UBI data and
> > partly old jffs2 data. I'm not sure what UBI does when it encounters
> > incorrect data, if it just erases the relevant blocks and formats them for
> > its own use, or if it barfs completely and just bails out complaining that
> > the partition does not contain UBI data. If the relevant blocks were
> > erased, then I think UBI would simply concede that the a previous erase
> > attempt had been prematurely aborted, and re-erase the blocks and write
> > its headers, so perhaps that is something to try. At any rate it involves
> > at least some mild trickery (erase the blocks that previously contained
> > jffs2 data).
> > 
> Yes, during mounting of UBIFS volumes, UBI checks for erase-header
> on first-page of every block. 

Mounting UBIFS volumes should not be a problem - the existing ones are
not located in the newly added area of the NAND.  The question however
is what the UBI layer itself does, if I for example try to create a
new volume which then would allocate blocks from the newly added
space.

> So, effectively you don't even need to erase the partition to convert
> it into UBI volume, you just try attaching it as UBI volume and UBI
> should erase it for you. (though flagging some warnings on the way).

Are you sure about that?

Well, I guess I'll have to try it out in the end...


Thanks!

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Deliver yesterday, code today, think tomorrow."


From sourav.poddar at ti.com  Wed Oct  9 11:24:41 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 9 Oct 2013 20:54:41 +0530
Subject: [PATCH 0/3]Add quad/memory mapped support for SPI flash. 
Message-ID: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>

This patch add quad/memory mapped support in flash driver(m25p80).

Added support for quad memory mapped for TI qspi controller also.

This patch has been tested with some internal dts data.

Sourav Poddar (3):
  spi/qspi: Add memory mapped read support.
  drivers: mtd: devices: Add quad read support.
  drivers: mtd: devices: Add memory mapped read support.

 drivers/mtd/devices/m25p80.c |  193 ++++++++++++++++++++++++++++++++++++++++--
 drivers/spi/spi-ti-qspi.c    |  140 +++++++++++++++++++++++++++---
 include/linux/spi/spi.h      |    2 +
 3 files changed, 312 insertions(+), 23 deletions(-)



From sourav.poddar at ti.com  Wed Oct  9 11:24:42 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 9 Oct 2013 20:54:42 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>

Qspi controller also supports memory mapped read. Patch
adds support for the same.
In memory mapped read, controller need to be switched to a
memory mapped port using a control module register and a qspi
specific register or just a qspi register.
Then the read need to be happened from the memory mapped
address space.

Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
---
 drivers/spi/spi-ti-qspi.c |  140 ++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 125 insertions(+), 15 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 0b71270..2722840 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -46,6 +46,8 @@ struct ti_qspi {
 
 	struct spi_master	*master;
 	void __iomem            *base;
+	void __iomem            *ctrl_base;
+	void __iomem            *mmap_base;
 	struct clk		*fclk;
 	struct device           *dev;
 
@@ -54,6 +56,9 @@ struct ti_qspi {
 	u32 spi_max_frequency;
 	u32 cmd;
 	u32 dc;
+
+	bool memory_mapped;
+	bool ctrl_mod;
 };
 
 #define QSPI_PID			(0x0)
@@ -109,6 +114,23 @@ struct ti_qspi {
 #define QSPI_CSPOL(n)			(1 << (1 + n * 8))
 #define QSPI_CKPOL(n)			(1 << (n * 8))
 
+#define	MM_SWITCH	0x01
+#define	MEM_CS		0x100
+#define	MEM_CS_DIS	0xfffff0ff
+
+#define	QSPI_CMD_RD		(0x3 << 0)
+#define	QSPI_CMD_DUAL_RD	(0x3b << 0)
+#define	QSPI_CMD_QUAD_RD	(0x6b << 0)
+#define	QSPI_CMD_READ_FAST	(0x0b << 0)
+#define	QSPI_SETUP0_A_BYTES	(0x3 << 8)
+#define	QSPI_SETUP0_NO_BITS	(0x0 << 10)
+#define	QSPI_SETUP0_8_BITS	(0x1 << 10)
+#define	QSPI_SETUP0_RD_NORMAL	(0x0 << 12)
+#define	QSPI_SETUP0_RD_DUAL	(0x1 << 12)
+#define	QSPI_SETUP0_RD_QUAD	(0x3 << 12)
+#define	QSPI_CMD_WRITE		(0x2 << 16)
+#define	QSPI_NUM_DUMMY_BITS	(0x0 << 24)
+
 #define	QSPI_FRAME			4096
 
 #define QSPI_AUTOSUSPEND_TIMEOUT         2000
@@ -125,12 +147,37 @@ static inline void ti_qspi_write(struct ti_qspi *qspi,
 	writel(val, qspi->base + reg);
 }
 
+void enable_qspi_memory_mapped(struct ti_qspi *qspi)
+{
+	u32 val;
+
+	ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+	if (qspi->ctrl_mod) {
+		val = readl(qspi->ctrl_base);
+		val |= MEM_CS;
+		writel(val, qspi->ctrl_base);
+	}
+}
+
+void disable_qspi_memory_mapped(struct ti_qspi *qspi)
+{
+	u32 val;
+
+	ti_qspi_write(qspi, ~MM_SWITCH, QSPI_SPI_SWITCH_REG);
+	if (qspi->ctrl_mod) {
+		val = readl(qspi->ctrl_base);
+		val |= MEM_CS_DIS;
+		writel(val, qspi->ctrl_base);
+	}
+}
+
 static int ti_qspi_setup(struct spi_device *spi)
 {
 	struct ti_qspi	*qspi = spi_master_get_devdata(spi->master);
 	struct ti_qspi_regs *ctx_reg = &qspi->ctx_reg;
 	int clk_div = 0, ret;
-	u32 clk_ctrl_reg, clk_rate, clk_mask;
+	u32 clk_ctrl_reg, clk_rate, clk_mask, memval = 0;
+	qspi->dc = 0;
 
 	if (spi->master->busy) {
 		dev_dbg(qspi->dev, "master busy doing other trasnfers\n");
@@ -178,6 +225,37 @@ static int ti_qspi_setup(struct spi_device *spi)
 	ti_qspi_write(qspi, clk_mask, QSPI_SPI_CLOCK_CNTRL_REG);
 	ctx_reg->clkctrl = clk_mask;
 
+	if (spi->mode & SPI_CPHA)
+		qspi->dc |= QSPI_CKPHA(spi->chip_select);
+	if (spi->mode & SPI_CPOL)
+		qspi->dc |= QSPI_CKPOL(spi->chip_select);
+	if (spi->mode & SPI_CS_HIGH)
+		qspi->dc |= QSPI_CSPOL(spi->chip_select);
+
+	ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG);
+
+	if (qspi->memory_mapped) {
+		switch (spi->mode) {
+		case SPI_TX_DUAL:
+			memval |= (QSPI_CMD_DUAL_RD | QSPI_SETUP0_A_BYTES |
+				QSPI_SETUP0_8_BITS | QSPI_SETUP0_RD_DUAL |
+				QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS);
+			break;
+		case SPI_TX_QUAD:
+			memval |= (QSPI_CMD_QUAD_RD | QSPI_SETUP0_A_BYTES |
+				QSPI_SETUP0_8_BITS | QSPI_SETUP0_RD_QUAD |
+				QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS);
+			break;
+		default:
+			memval |= (QSPI_CMD_RD | QSPI_SETUP0_A_BYTES |
+				QSPI_SETUP0_NO_BITS | QSPI_SETUP0_RD_NORMAL |
+				QSPI_CMD_WRITE | QSPI_NUM_DUMMY_BITS);
+			break;
+		}
+		ti_qspi_write(qspi, memval, QSPI_SPI_SETUP0_REG);
+		spi->mode |= SPI_RX_MMAP;
+	}
+
 	pm_runtime_mark_last_busy(qspi->dev);
 	ret = pm_runtime_put_autosuspend(qspi->dev);
 	if (ret < 0) {
@@ -340,16 +418,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,
 	struct spi_transfer *t;
 	int status = 0, ret;
 	int frame_length;
-
-	/* setup device control reg */
-	qspi->dc = 0;
-
-	if (spi->mode & SPI_CPHA)
-		qspi->dc |= QSPI_CKPHA(spi->chip_select);
-	if (spi->mode & SPI_CPOL)
-		qspi->dc |= QSPI_CKPOL(spi->chip_select);
-	if (spi->mode & SPI_CS_HIGH)
-		qspi->dc |= QSPI_CSPOL(spi->chip_select);
+	size_t from = 0;
 
 	frame_length = (m->frame_length << 3) / spi->bits_per_word;
 
@@ -362,11 +431,21 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,
 	qspi->cmd |= QSPI_WC_CMD_INT_EN;
 
 	ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG);
-	ti_qspi_write(qspi, qspi->dc, QSPI_SPI_DC_REG);
 
 	mutex_lock(&qspi->list_lock);
 
 	list_for_each_entry(t, &m->transfers, transfer_list) {
+		if (t->memory_map) {
+			if (t->tx_buf) {
+				from = t->len;
+				continue;
+			}
+			enable_qspi_memory_mapped(qspi);
+			memcpy(t->rx_buf, qspi->mmap_base + from, t->len);
+			disable_qspi_memory_mapped(qspi);
+			goto out;
+		}
+
 		qspi->cmd |= QSPI_WLEN(t->bits_per_word);
 
 		ret = qspi_transfer_msg(qspi, t);
@@ -379,6 +458,7 @@ static int ti_qspi_start_transfer_one(struct spi_master *master,
 		m->actual_length += t->len;
 	}
 
+out:
 	mutex_unlock(&qspi->list_lock);
 
 	m->status = status;
@@ -437,7 +517,7 @@ static int ti_qspi_probe(struct platform_device *pdev)
 {
 	struct  ti_qspi *qspi;
 	struct spi_master *master;
-	struct resource         *r;
+	struct resource         *r, *res_ctrl, *res_mmap;
 	struct device_node *np = pdev->dev.of_node;
 	u32 max_freq;
 	int ret = 0, num_cs, irq;
@@ -446,7 +526,8 @@ static int ti_qspi_probe(struct platform_device *pdev)
 	if (!master)
 		return -ENOMEM;
 
-	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
+					SPI_RX_MMAP;
 
 	master->bus_num = -1;
 	master->flags = SPI_MASTER_HALF_DUPLEX;
@@ -465,7 +546,16 @@ static int ti_qspi_probe(struct platform_device *pdev)
 	qspi->master = master;
 	qspi->dev = &pdev->dev;
 
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_base");
+	if (r == NULL) {
+		dev_err(&pdev->dev, "missing platform resources data\n");
+		return -ENODEV;
+	}
+
+	res_mmap = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "qspi_mmap");
+	res_ctrl = platform_get_resource_byname(pdev,
+				IORESOURCE_MEM, "qspi_ctrlmod");
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -481,6 +571,23 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		goto free_master;
 	}
 
+	if (res_ctrl) {
+		qspi->ctrl_mod = true;
+		qspi->ctrl_base = devm_ioremap_resource(&pdev->dev, res_ctrl);
+		if (IS_ERR(qspi->ctrl_base)) {
+			ret = PTR_ERR(qspi->ctrl_base);
+			goto free_master;
+		}
+	}
+
+	if (res_mmap) {
+		qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap);
+		if (IS_ERR(qspi->mmap_base)) {
+			ret = PTR_ERR(qspi->mmap_base);
+			goto free_master;
+		}
+	}
+
 	ret = devm_request_irq(&pdev->dev, irq, ti_qspi_isr, 0,
 			dev_name(&pdev->dev), qspi);
 	if (ret < 0) {
@@ -504,6 +611,9 @@ static int ti_qspi_probe(struct platform_device *pdev)
 	if (!of_property_read_u32(np, "spi-max-frequency", &max_freq))
 		qspi->spi_max_frequency = max_freq;
 
+	if (of_property_read_bool(np, "mmap_read"))
+		qspi->memory_mapped = true;
+
 	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret)
 		goto free_master;
-- 
1.7.1



From sourav.poddar at ti.com  Wed Oct  9 11:24:43 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 9 Oct 2013 20:54:43 +0530
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>

Some flash also support quad read mode.
Adding support for adding quad mode in m25p80
for spansion and macronix flash.

Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
---
v2->v3:
Add macronix flash support
 drivers/mtd/devices/m25p80.c |  184 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 176 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 26b14f9..dc9bcbf 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -41,6 +41,7 @@
 #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
 #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ        0x6b    /* QUAD READ */
 #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
 #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
 #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
@@ -48,6 +49,7 @@
 #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
+#define	OPCODE_RDCR		0x35    /* Read configuration register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
@@ -76,6 +78,10 @@
 #define	SR_BP2			0x10	/* Block protect 2 */
 #define	SR_SRWD			0x80	/* SR write protect */
 
+/* Configuration Register bits. */
+#define SPAN_QUAD_CR_EN		0x2	/* Spansion Quad I/O */
+#define MACR_QUAD_SR_EN		0x40	/* Macronix Quad I/O */
+
 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
 #define	MAX_CMD_SIZE		5
@@ -95,6 +101,7 @@ struct m25p {
 	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
+	bool			quad_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)
 	return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
 }
 
+/* Read the configuration register, returning its value in the location
+ * Return the configuration register value.
+ * Returns negative if error occurred.
+*/
+static int read_cr(struct m25p *flash)
+{
+	u8 code = OPCODE_RDCR;
+	int ret;
+	u8 val;
+
+	ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
 /*
  * Enable/disable 4-byte addressing mode.
  */
@@ -336,6 +362,122 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
 	return 0;
 }
 
+/* Write status register and configuration register with 2 bytes
+* The first byte will be written to the status register, while the second byte
+* will be written to the configuration register.
+* Returns negative if error occurred.
+*/
+static int write_sr_cr(struct m25p *flash, u16 val)
+{
+	flash->command[0] = OPCODE_WRSR;
+	flash->command[1] = val & 0xff;
+	flash->command[2] = (val >> 8);
+
+	return spi_write(flash->spi, flash->command, 3);
+}
+
+static int macronix_quad_enable(struct m25p *flash)
+{
+	int ret, val;
+	u8 cmd[2];
+	cmd[0] = OPCODE_WRSR;
+
+	val = read_sr(flash);
+	cmd[1] = val | MACR_QUAD_SR_EN;
+	write_enable(flash);
+
+	spi_write(flash->spi, &cmd, 2);
+
+	if (wait_till_ready(flash))
+		return 1;
+
+	ret = read_sr(flash);
+	if (!(ret > 0 && (ret & MACR_QUAD_SR_EN))) {
+		dev_err(&flash->spi->dev,
+			"Macronix Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int spansion_quad_enable(struct m25p *flash)
+{
+	int ret;
+	int quad_en = SPAN_QUAD_CR_EN << 8;
+
+	write_enable(flash);
+
+	ret = write_sr_cr(flash, quad_en);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev,
+			"error while writing configuration register");
+		return -EINVAL;
+	}
+
+	/* read back and check it */
+	ret = read_cr(flash);
+	if (!(ret > 0 && (ret & SPAN_QUAD_CR_EN))) {
+		dev_err(&flash->spi->dev,
+			"Spansion Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
+	size_t *retlen, u_char *buf)
+{
+	struct m25p *flash = mtd_to_m25p(mtd);
+	struct spi_transfer t[2];
+	struct spi_message m;
+	uint8_t opcode;
+
+	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
+			__func__, (u32)from, len);
+
+	spi_message_init(&m);
+	memset(t, 0, (sizeof(t)));
+
+	t[0].tx_buf = flash->command;
+	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
+	spi_message_add_tail(&t[0], &m);
+
+	t[1].rx_buf = buf;
+	t[1].len = len;
+	t[1].rx_nbits = SPI_NBITS_QUAD;
+	spi_message_add_tail(&t[1], &m);
+
+	mutex_lock(&flash->lock);
+
+	/* Wait till previous write/erase is done. */
+	if (wait_till_ready(flash)) {
+		/* REVISIT status return?? */
+		mutex_unlock(&flash->lock);
+		return 1;
+	}
+
+	/* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
+	 * clocks; and at this writing, every chip this driver handles
+	 * supports that opcode.
+	*/
+
+	/* Set up the write data buffer. */
+	opcode = flash->read_opcode;
+	flash->command[0] = opcode;
+	m25p_addr2cmd(flash, from, flash->command);
+
+	spi_sync(flash->spi, &m);
+
+	*retlen = m.actual_length - m25p_cmdsz(flash) -
+			(flash->quad_read ? 1 : 0);
+
+	mutex_unlock(&flash->lock);
+
+	return 0;
+}
+
 /*
  * Read an address range from the flash chip.  The address range
  * may be any size provided it is within the physical boundaries.
@@ -928,6 +1070,7 @@ static int m25p_probe(struct spi_device *spi)
 	unsigned			i;
 	struct mtd_part_parser_data	ppdata;
 	struct device_node __maybe_unused *np = spi->dev.of_node;
+	int ret;
 
 #ifdef CONFIG_MTD_OF_PARTS
 	if (!of_device_is_available(np))
@@ -979,15 +1122,9 @@ static int m25p_probe(struct spi_device *spi)
 		}
 	}
 
-	flash = kzalloc(sizeof *flash, GFP_KERNEL);
+	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
 	if (!flash)
 		return -ENOMEM;
-	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
-					GFP_KERNEL);
-	if (!flash->command) {
-		kfree(flash);
-		return -ENOMEM;
-	}
 
 	flash->spi = spi;
 	mutex_init(&flash->lock);
@@ -1015,7 +1152,6 @@ static int m25p_probe(struct spi_device *spi)
 	flash->mtd.flags = MTD_CAP_NORFLASH;
 	flash->mtd.size = info->sector_size * info->n_sectors;
 	flash->mtd._erase = m25p80_erase;
-	flash->mtd._read = m25p80_read;
 
 	/* flash protection support for STmicro chips */
 	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
@@ -1067,6 +1203,38 @@ static int m25p_probe(struct spi_device *spi)
 
 	flash->program_opcode = OPCODE_PP;
 
+	flash->quad_read = false;
+	if (spi->mode && SPI_RX_QUAD)
+		flash->quad_read = true;
+
+	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
+				(flash->quad_read ? 1 : 0)), GFP_KERNEL);
+	if (!flash->command) {
+		kfree(flash);
+		return -ENOMEM;
+	}
+
+	if (flash->quad_read) {
+		if (of_property_read_bool(np, "macronix,quad_enable")) {
+			ret = macronix_quad_enable(flash);
+			if (ret) {
+				dev_err(&spi->dev,
+					"error enabling quad");
+				return -EINVAL;
+			}
+		} else if (of_property_read_bool(np, "spansion,quad_enable")) {
+			ret = spansion_quad_enable(flash);
+			if (ret) {
+				dev_err(&spi->dev,
+					"error enabling quad");
+				return -EINVAL;
+			}
+		} else
+			dev_dbg(&spi->dev, "quad enable not supported");
+		flash->mtd._read = m25p80_quad_read;
+	} else
+		flash->mtd._read = m25p80_read;
+
 	if (info->addr_width)
 		flash->addr_width = info->addr_width;
 	else if (flash->mtd.size > 0x1000000) {
-- 
1.7.1



From sourav.poddar at ti.com  Wed Oct  9 11:24:44 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 9 Oct 2013 20:54:44 +0530
Subject: [RFC/PATCH 3/3] drivers: mtd: devices: Add memory mapped read support.
In-Reply-To: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <1381332284-21822-4-git-send-email-sourav.poddar@ti.com>

Add memory mapped flash read support. In memory mapped, only the len, from
and t->rx_buf is required from the flash side, while other configuration
will be taken care of from the respective controller side with the help
of the transfer flag(memory_map).

Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
---

 drivers/mtd/devices/m25p80.c |   13 +++++++++++--
 include/linux/spi/spi.h      |    2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index dc9bcbf..9d09bad 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -102,6 +102,7 @@ struct m25p {
 	u8			*command;
 	bool			fast_read;
 	bool			quad_read;
+	bool			mmap_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -440,10 +441,15 @@ static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
 	spi_message_init(&m);
 	memset(t, 0, (sizeof(t)));
 
+	if (flash->mmap_read)
+		t[0].memory_map = 1;
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
+	t[0].len = flash->mmap_read ? from : m25p_cmdsz(flash) +
+				(flash->quad_read ? 1 : 0);
 	spi_message_add_tail(&t[0], &m);
 
+	if (flash->mmap_read)
+		t[1].memory_map = 1;
 	t[1].rx_buf = buf;
 	t[1].len = len;
 	t[1].rx_nbits = SPI_NBITS_QUAD;
@@ -470,7 +476,7 @@ static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
 
 	spi_sync(flash->spi, &m);
 
-	*retlen = m.actual_length - m25p_cmdsz(flash) -
+	*retlen = flash->mmap_read ? len : m.actual_length - m25p_cmdsz(flash) -
 			(flash->quad_read ? 1 : 0);
 
 	mutex_unlock(&flash->lock);
@@ -1207,6 +1213,9 @@ static int m25p_probe(struct spi_device *spi)
 	if (spi->mode && SPI_RX_QUAD)
 		flash->quad_read = true;
 
+	if (spi->mode && SPI_RX_MMAP)
+		flash->mmap_read = true;
+
 	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
 				(flash->quad_read ? 1 : 0)), GFP_KERNEL);
 	if (!flash->command) {
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 4d634d6..a6ffb52 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -91,6 +91,7 @@ struct spi_device {
 #define	SPI_TX_QUAD	0x200			/* transmit with 4 wires */
 #define	SPI_RX_DUAL	0x400			/* receive with 2 wires */
 #define	SPI_RX_QUAD	0x800			/* receive with 4 wires */
+#define SPI_RX_MMAP	0x1000			/* Memory mapped read */
 	u8			bits_per_word;
 	int			irq;
 	void			*controller_state;
@@ -557,6 +558,7 @@ struct spi_transfer {
 	u16		delay_usecs;
 	u32		speed_hz;
 
+	bool	memory_map;
 	struct list_head transfer_list;
 };
 
-- 
1.7.1



From broonie at kernel.org  Wed Oct  9 11:45:33 2013
From: broonie at kernel.org (Mark Brown)
Date: Wed, 9 Oct 2013 16:45:33 +0100
Subject: [RFC/PATCH 3/3] drivers: mtd: devices: Add memory mapped read
 support.
In-Reply-To: <1381332284-21822-4-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-4-git-send-email-sourav.poddar@ti.com>
Message-ID: <20131009154533.GP21581@sirena.org.uk>

On Wed, Oct 09, 2013 at 08:54:44PM +0530, Sourav Poddar wrote:

>  drivers/mtd/devices/m25p80.c |   13 +++++++++++--
>  include/linux/spi/spi.h      |    2 ++

You shouldn't be adding the SPI feature in the same change as you add
the user.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/362bdaf8/attachment.sig>

From ricard.wanderlof at axis.com  Wed Oct  9 11:45:57 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Wed, 9 Oct 2013 17:45:57 +0200
Subject: Grow UBI device?
In-Reply-To: <20131009150538.BAD57380432@gemini.denx.de>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
 <20131009150538.BAD57380432@gemini.denx.de>
Message-ID: <alpine.DEB.2.00.1310091725590.28562@lnxricardw.se.axis.com>


On Wed, 9 Oct 2013, Wolfgang Denk wrote:

>>> Come to think of it, I'm not sure that would work anyway, as the
>>> resulting, new, enlarged partition would partly contain UBI data and
>>> partly old jffs2 data. I'm not sure what UBI does when it encounters
>>> incorrect data, if it just erases the relevant blocks and formats them for
>>> its own use, or if it barfs completely and just bails out complaining that
>>> the partition does not contain UBI data. If the relevant blocks were
>>> erased, then I think UBI would simply concede that the a previous erase
>>> attempt had been prematurely aborted, and re-erase the blocks and write
>>> its headers, so perhaps that is something to try. At any rate it involves
>>> at least some mild trickery (erase the blocks that previously contained
>>> jffs2 data).
>>>
>> Yes, during mounting of UBIFS volumes, UBI checks for erase-header
>> on first-page of every block.
>
> Mounting UBIFS volumes should not be a problem - the existing ones are
> not located in the newly added area of the NAND.  The question however
> is what the UBI layer itself does, if I for example try to create a
> new volume which then would allocate blocks from the newly added
> space.

UBI scans the whole partition when the attachement is made to the mtd 
partition. So if you'd get any error message regarding blocks that lack 
UBI headers it would be then, not when you subsequently try to create a 
volume in the partition. By that time the volume should be "formatted" 
with valid UBI headers.

>> So, effectively you don't even need to erase the partition to convert
>> it into UBI volume, you just try attaching it as UBI volume and UBI
>> should erase it for you. (though flagging some warnings on the way).
>
> Are you sure about that?
>
> Well, I guess I'll have to try it out in the end...

I just tested it since I have a UBI system just beside me, by erasing and 
then writing zeros to a block (just to put non-UBI data in it) and 
restarting the system (the partition in question contains the volume with 
the root file system in it, so it is attached by the kernel during its 
boot). The result was that UBI didn't give any error or warning messages 
during boot, but a subsequent nanddump after boot revealed that the 
zeroed blocks now contained valid UBI headers, so, without looking at the 
source, it seems that UBI really does manage this fairly silently.

/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 broonie at kernel.org  Wed Oct  9 12:07:59 2013
From: broonie at kernel.org (Mark Brown)
Date: Wed, 9 Oct 2013 17:07:59 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
Message-ID: <20131009160759.GQ21581@sirena.org.uk>

On Wed, Oct 09, 2013 at 08:54:42PM +0530, Sourav Poddar wrote:

> Qspi controller also supports memory mapped read. Patch
> adds support for the same.
> In memory mapped read, controller need to be switched to a
> memory mapped port using a control module register and a qspi
> specific register or just a qspi register.
> Then the read need to be happened from the memory mapped
> address space.

Can you provide more details on what exactly this means?  Looking at the
code it looks awfully like this has the same problem that the Freescale
code had with needing to know the commands the flash needs?

I'm also concerned about the interface here, it looks like this is being
made visible to SPI devices (via a dependency on patch 3/3...) but only
as a flag they can set - how would devices know to enable this and why
would they want to avoid it?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/849a88a5/attachment.sig>

From sourav.poddar at ti.com  Wed Oct  9 12:54:33 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 9 Oct 2013 22:24:33 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131009160759.GQ21581@sirena.org.uk>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk>
Message-ID: <52558A49.5090904@ti.com>

On Wednesday 09 October 2013 09:37 PM, Mark Brown wrote:
> On Wed, Oct 09, 2013 at 08:54:42PM +0530, Sourav Poddar wrote:
>
>> Qspi controller also supports memory mapped read. Patch
>> adds support for the same.
>> In memory mapped read, controller need to be switched to a
>> memory mapped port using a control module register and a qspi
>> specific register or just a qspi register.
>> Then the read need to be happened from the memory mapped
>> address space.
> Can you provide more details on what exactly this means?  Looking at the
> code it looks awfully like this has the same problem that the Freescale
> code had with needing to know the commands the flash needs?
Here is the exact feature usecase..
TI qspi controller supports memory mapped read. These memory
mapped read configuration depends on the set_up_register, which
can be configured once during in setup apis based on the dt node
specifying whether the qspi controller supports memory mapped read
or not.
Once, the qspi controller is configured for a memory mapped read, the qspi
controller does not depend on the flash command that comes from the mtd 
layer.
Because, this command are already configured in QSPI set up register.

To use qspi in memory mapped mode, we need to switch to memory mapped port
using certain registers(for am43x its only qspi register, while for 
dra7x its qspi register
as well as control module register) and once the memory mapped read is 
done, switch
back to configuration mode register.

Basically, its not the commands which need to be communicated from the 
mtd layer,its just
the buffer to fill, len of buffer, offset from where to fill need to be 
communicated.

> I'm also concerned about the interface here, it looks like this is being
> made visible to SPI devices (via a dependency on patch 3/3...) but only
> as a flag they can set - how would devices know to enable this and why
> would they want to avoid it?
Set  spi->mode in qspi driver based on dt entry and use that in mtd layer to
decide whether to use memory mapped or not.

The idea is whenever, we call mtd_read api from mtd layer, if memory 
mapped is set
then sending the commands does not matter, what matters is the len to 
read, buffer to fill and
"from" offset to read. Then, the intention was to use the memory_map 
transfer parameter to
communicate to the driver that memory mapped read is used so that we can 
just use memcopy and
return without going through the entire SPI based xfer function.





From computersforpeace at gmail.com  Wed Oct  9 13:06:49 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 10:06:49 -0700
Subject: [PATCH/TRIVIAL] mtd: Use MTD_BLOCK_MAJOR instead of the magic
 number
In-Reply-To: <20131009120221.GB31294@localhost>
References: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAN8TOE-9XRW9QJ7+sSis+Omo0eVAGVHOXD70P4L8FNbLut=9Dg@mail.gmail.com>
 <20131009120221.GB31294@localhost>
Message-ID: <CAN8TOE84raS7thT5ZU1Zpa7SQO7ocmmOdhrR7KxohQVsJix3Pg@mail.gmail.com>

On Wed, Oct 9, 2013 at 5:02 AM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> On Tue, Oct 08, 2013 at 06:15:21PM -0700, Brian Norris wrote:
>> Why does MTD_BLOCK_MAJOR (and MTD_CHAR_MAJOR) live in
>> include/linux/mtd/mtd.h and not include/uapi/linux/major.h?
>
> Ah, nice catch. How about something like this?
>
> diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
> index f9bfe52..9e1471e 100644
> --- a/include/linux/mtd/mtd.h
> +++ b/include/linux/mtd/mtd.h
> @@ -24,14 +24,12 @@
>  #include <linux/uio.h>
>  #include <linux/notifier.h>
>  #include <linux/device.h>
> +#include <linux/major.h>

I think it's a (weak?) style preference that this type of #include
just go in the files that need it (there are only a few -- 4 I think?)
rather than importing it directly into the mtd.h header for all users.
But I don't object strongly.

>  #include <mtd/mtd-abi.h>
>
>  #include <asm/div64.h>
>
> -#define MTD_CHAR_MAJOR 90
> -#define MTD_BLOCK_MAJOR 31
> -
>  #define MTD_ERASE_PENDING      0x01
>  #define MTD_ERASING            0x02
>  #define MTD_ERASE_SUSPEND      0x04
> diff --git a/include/uapi/linux/major.h b/include/uapi/linux/major.h
> index 6a8ca98..620252e 100644
> --- a/include/uapi/linux/major.h
> +++ b/include/uapi/linux/major.h
> @@ -54,6 +54,7 @@
>  #define ACSI_MAJOR             28
>  #define AZTECH_CDROM_MAJOR     29
>  #define FB_MAJOR               29   /* /dev/fb* framebuffers */
> +#define MTD_BLOCK_MAJOR                31
>  #define CM206_CDROM_MAJOR      32
>  #define IDE2_MAJOR             33
>  #define IDE3_MAJOR             34
> @@ -105,6 +106,7 @@
>  #define IDE6_MAJOR             88
>  #define IDE7_MAJOR             89
>  #define IDE8_MAJOR             90
> +#define MTD_CHAR_MAJOR         90
>  #define IDE9_MAJOR             91
>
>  #define DASD_MAJOR             94
>
> --
>
> If you think this is OK, you can take this patch and I'll cook
> another one moving MTD_xxx_MAJOR as above.

Yeah, the original patch here is good. I'll run it through the build
tests and then apply it. Feel free to send a proper follow-up with
either the diff you just sent or with the #include <linux/major.h>
moved into the appropriate .c files.

Thanks,
Brian


From broonie at kernel.org  Wed Oct  9 13:40:27 2013
From: broonie at kernel.org (Mark Brown)
Date: Wed, 9 Oct 2013 18:40:27 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <52558A49.5090904@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
Message-ID: <20131009174027.GS21581@sirena.org.uk>

On Wed, Oct 09, 2013 at 10:24:33PM +0530, Sourav Poddar wrote:

> Here is the exact feature usecase..
> TI qspi controller supports memory mapped read. These memory
> mapped read configuration depends on the set_up_register, which
> can be configured once during in setup apis based on the dt node
> specifying whether the qspi controller supports memory mapped read
> or not.

What is "set_up_register"?

> Once, the qspi controller is configured for a memory mapped read, the qspi
> controller does not depend on the flash command that comes from the
> mtd layer.
> Because, this command are already configured in QSPI set up register.

So this does depend on the flash commands for the specific chip, which
means that this has all the same problems as the Freescale chip had with
requiring the user to replicate the information about the commands that
the chip supports into the device tree.  It therefore seems like all the
same concerns should apply, though in this case it seems like it's
harder for the driver to infer things from looking at the operations
being sent to it.

Presumably this also only works for flash chips, or things that look
like them...

> Basically, its not the commands which need to be communicated from
> the mtd layer,its just
> the buffer to fill, len of buffer, offset from where to fill need to
> be communicated.

This appears to be based on an assumption that the commands would be
replicated into the device trees which seems like it's both more work
for users and harder to deploy.

> >I'm also concerned about the interface here, it looks like this is being
> >made visible to SPI devices (via a dependency on patch 3/3...) but only
> >as a flag they can set - how would devices know to enable this and why
> >would they want to avoid it?

> Set  spi->mode in qspi driver based on dt entry and use that in mtd layer to
> decide whether to use memory mapped or not.

But why would anything not want to use memory mapped mode if it can and
why is this something that should be hard coded into the device tree?
Especially with the current API...

> The idea is whenever, we call mtd_read api from mtd layer, if memory
> mapped is set
> then sending the commands does not matter, what matters is the len
> to read, buffer to fill and
> "from" offset to read. Then, the intention was to use the memory_map
> transfer parameter to
> communicate to the driver that memory mapped read is used so that we
> can just use memcopy and
> return without going through the entire SPI based xfer function.

I'm not convinced that this is the most useful API, it sounds like the
hardware can "memory map" the entire flash chip so the whole SPI
framework seems like overhead.

It also seems seems like it's going to involve the CPU being stalled
waiting for reads to complete instead of asking the SPI controller to
DMA the data to RAM and allowing the CPU to get on with other things -
replacing the explicit transmission of commands with memory to memory
DMAs might be advantageous but replacing DMA with memcpy() would need
numbers to show that it was a win.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/1a54b432/attachment.sig>

From jagannadh.teki at gmail.com  Wed Oct  9 14:15:11 2013
From: jagannadh.teki at gmail.com (Jagan Teki)
Date: Wed, 9 Oct 2013 23:45:11 +0530
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
Message-ID: <CAD6G_RShZMkSpVzvXWEE0+sDX=pcnf7ndChndgDG5_T4EVL2vQ@mail.gmail.com>

On Wed, Oct 9, 2013 at 8:54 PM, Sourav Poddar <sourav.poddar at ti.com> wrote:
> Some flash also support quad read mode.
> Adding support for adding quad mode in m25p80
> for spansion and macronix flash.

I am some how not happy with this approach, adding a flags on flash
param table for supporting
quad operation in specific flash is may be a better idea.

But reading SFDP, is a good idea to get the details of flash - quad
support is one of them.
and we can assign quad read or fast read based on that.

Any comments.

>
> Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
> v2->v3:
> Add macronix flash support
>  drivers/mtd/devices/m25p80.c |  184 ++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 176 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 26b14f9..dc9bcbf 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -41,6 +41,7 @@
>  #define        OPCODE_WRSR             0x01    /* Write status register 1 byte */
>  #define        OPCODE_NORM_READ        0x03    /* Read data bytes (low frequency) */
>  #define        OPCODE_FAST_READ        0x0b    /* Read data bytes (high frequency) */
> +#define        OPCODE_QUAD_READ        0x6b    /* QUAD READ */
>  #define        OPCODE_PP               0x02    /* Page program (up to 256 bytes) */
>  #define        OPCODE_BE_4K            0x20    /* Erase 4KiB block */
>  #define        OPCODE_BE_4K_PMC        0xd7    /* Erase 4KiB block on PMC chips */
> @@ -48,6 +49,7 @@
>  #define        OPCODE_CHIP_ERASE       0xc7    /* Erase whole flash chip */
>  #define        OPCODE_SE               0xd8    /* Sector erase (usually 64KiB) */
>  #define        OPCODE_RDID             0x9f    /* Read JEDEC ID */
> +#define        OPCODE_RDCR             0x35    /* Read configuration register */
>
>  /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>  #define        OPCODE_NORM_READ_4B     0x13    /* Read data bytes (low frequency) */
> @@ -76,6 +78,10 @@
>  #define        SR_BP2                  0x10    /* Block protect 2 */
>  #define        SR_SRWD                 0x80    /* SR write protect */
>
> +/* Configuration Register bits. */
> +#define SPAN_QUAD_CR_EN                0x2     /* Spansion Quad I/O */
> +#define MACR_QUAD_SR_EN                0x40    /* Macronix Quad I/O */
> +
>  /* Define max times to check status register before we give up. */
>  #define        MAX_READY_WAIT_JIFFIES  (40 * HZ)       /* M25P16 specs 40s max chip erase */
>  #define        MAX_CMD_SIZE            5
> @@ -95,6 +101,7 @@ struct m25p {
>         u8                      program_opcode;
>         u8                      *command;
>         bool                    fast_read;
> +       bool                    quad_read;
>  };
>
>  static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
> @@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)
>         return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
>  }
>
> +/* Read the configuration register, returning its value in the location
> + * Return the configuration register value.
> + * Returns negative if error occurred.
> +*/
> +static int read_cr(struct m25p *flash)
> +{
> +       u8 code = OPCODE_RDCR;
> +       int ret;
> +       u8 val;
> +
> +       ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
> +       if (ret < 0) {
> +               dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
> +               return ret;
> +       }
> +
> +       return val;
> +}
> +
>  /*
>   * Enable/disable 4-byte addressing mode.
>   */
> @@ -336,6 +362,122 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
>         return 0;
>  }
>
> +/* Write status register and configuration register with 2 bytes
> +* The first byte will be written to the status register, while the second byte
> +* will be written to the configuration register.
> +* Returns negative if error occurred.
> +*/
> +static int write_sr_cr(struct m25p *flash, u16 val)
> +{
> +       flash->command[0] = OPCODE_WRSR;
> +       flash->command[1] = val & 0xff;
> +       flash->command[2] = (val >> 8);
> +
> +       return spi_write(flash->spi, flash->command, 3);
> +}
> +
> +static int macronix_quad_enable(struct m25p *flash)
> +{
> +       int ret, val;
> +       u8 cmd[2];
> +       cmd[0] = OPCODE_WRSR;
> +
> +       val = read_sr(flash);
> +       cmd[1] = val | MACR_QUAD_SR_EN;
> +       write_enable(flash);
> +
> +       spi_write(flash->spi, &cmd, 2);
> +
> +       if (wait_till_ready(flash))
> +               return 1;
> +
> +       ret = read_sr(flash);
> +       if (!(ret > 0 && (ret & MACR_QUAD_SR_EN))) {
> +               dev_err(&flash->spi->dev,
> +                       "Macronix Quad bit not set");
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int spansion_quad_enable(struct m25p *flash)
> +{
> +       int ret;
> +       int quad_en = SPAN_QUAD_CR_EN << 8;
> +
> +       write_enable(flash);
> +
> +       ret = write_sr_cr(flash, quad_en);
> +       if (ret < 0) {
> +               dev_err(&flash->spi->dev,
> +                       "error while writing configuration register");
> +               return -EINVAL;
> +       }
> +
> +       /* read back and check it */
> +       ret = read_cr(flash);
> +       if (!(ret > 0 && (ret & SPAN_QUAD_CR_EN))) {
> +               dev_err(&flash->spi->dev,
> +                       "Spansion Quad bit not set");
> +               return -EINVAL;
> +       }
> +
> +       return 0;
> +}
> +
> +static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
> +       size_t *retlen, u_char *buf)
> +{
> +       struct m25p *flash = mtd_to_m25p(mtd);
> +       struct spi_transfer t[2];
> +       struct spi_message m;
> +       uint8_t opcode;
> +
> +       pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
> +                       __func__, (u32)from, len);
> +
> +       spi_message_init(&m);
> +       memset(t, 0, (sizeof(t)));
> +
> +       t[0].tx_buf = flash->command;
> +       t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
> +       spi_message_add_tail(&t[0], &m);
> +
> +       t[1].rx_buf = buf;
> +       t[1].len = len;
> +       t[1].rx_nbits = SPI_NBITS_QUAD;
> +       spi_message_add_tail(&t[1], &m);
> +
> +       mutex_lock(&flash->lock);
> +
> +       /* Wait till previous write/erase is done. */
> +       if (wait_till_ready(flash)) {
> +               /* REVISIT status return?? */
> +               mutex_unlock(&flash->lock);
> +               return 1;
> +       }
> +
> +       /* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
> +        * clocks; and at this writing, every chip this driver handles
> +        * supports that opcode.
> +       */
> +
> +       /* Set up the write data buffer. */
> +       opcode = flash->read_opcode;
> +       flash->command[0] = opcode;
> +       m25p_addr2cmd(flash, from, flash->command);
> +
> +       spi_sync(flash->spi, &m);
> +
> +       *retlen = m.actual_length - m25p_cmdsz(flash) -
> +                       (flash->quad_read ? 1 : 0);
> +
> +       mutex_unlock(&flash->lock);
> +
> +       return 0;
> +}
> +
>  /*
>   * Read an address range from the flash chip.  The address range
>   * may be any size provided it is within the physical boundaries.
> @@ -928,6 +1070,7 @@ static int m25p_probe(struct spi_device *spi)
>         unsigned                        i;
>         struct mtd_part_parser_data     ppdata;
>         struct device_node __maybe_unused *np = spi->dev.of_node;
> +       int ret;
>
>  #ifdef CONFIG_MTD_OF_PARTS
>         if (!of_device_is_available(np))
> @@ -979,15 +1122,9 @@ static int m25p_probe(struct spi_device *spi)
>                 }
>         }
>
> -       flash = kzalloc(sizeof *flash, GFP_KERNEL);
> +       flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
>         if (!flash)
>                 return -ENOMEM;
> -       flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
> -                                       GFP_KERNEL);
> -       if (!flash->command) {
> -               kfree(flash);
> -               return -ENOMEM;
> -       }
>
>         flash->spi = spi;
>         mutex_init(&flash->lock);
> @@ -1015,7 +1152,6 @@ static int m25p_probe(struct spi_device *spi)
>         flash->mtd.flags = MTD_CAP_NORFLASH;
>         flash->mtd.size = info->sector_size * info->n_sectors;
>         flash->mtd._erase = m25p80_erase;
> -       flash->mtd._read = m25p80_read;
>
>         /* flash protection support for STmicro chips */
>         if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
> @@ -1067,6 +1203,38 @@ static int m25p_probe(struct spi_device *spi)
>
>         flash->program_opcode = OPCODE_PP;
>
> +       flash->quad_read = false;
> +       if (spi->mode && SPI_RX_QUAD)
> +               flash->quad_read = true;
> +
> +       flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
> +                               (flash->quad_read ? 1 : 0)), GFP_KERNEL);
> +       if (!flash->command) {
> +               kfree(flash);
> +               return -ENOMEM;
> +       }
> +
> +       if (flash->quad_read) {
> +               if (of_property_read_bool(np, "macronix,quad_enable")) {
> +                       ret = macronix_quad_enable(flash);
> +                       if (ret) {
> +                               dev_err(&spi->dev,
> +                                       "error enabling quad");
> +                               return -EINVAL;
> +                       }
> +               } else if (of_property_read_bool(np, "spansion,quad_enable")) {
> +                       ret = spansion_quad_enable(flash);
> +                       if (ret) {
> +                               dev_err(&spi->dev,
> +                                       "error enabling quad");
> +                               return -EINVAL;
> +                       }
> +               } else
> +                       dev_dbg(&spi->dev, "quad enable not supported");
> +               flash->mtd._read = m25p80_quad_read;
> +       } else
> +               flash->mtd._read = m25p80_read;
> +
>         if (info->addr_width)
>                 flash->addr_width = info->addr_width;
>         else if (flash->mtd.size > 0x1000000) {
> --
> 1.7.1
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/

-- 
Thanks,
Jagan.
--------
Jagannadha Sutradharudu Teki,
E: jagannadh.teki at gmail.com, P: +91-9676773388
Engineer - System Software Hacker
U-boot - SPI Custodian and Zynq APSOC
Ln: http://www.linkedin.com/in/jaganteki


From sourav.poddar at ti.com  Wed Oct  9 14:15:46 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 9 Oct 2013 23:45:46 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131009174027.GS21581@sirena.org.uk>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>
Message-ID: <52559D52.4010400@ti.com>

On Wednesday 09 October 2013 11:10 PM, Mark Brown wrote:
> On Wed, Oct 09, 2013 at 10:24:33PM +0530, Sourav Poddar wrote:
>
>> Here is the exact feature usecase..
>> TI qspi controller supports memory mapped read. These memory
>> mapped read configuration depends on the set_up_register, which
>> can be configured once during in setup apis based on the dt node
>> specifying whether the qspi controller supports memory mapped read
>> or not.
> What is "set_up_register"?
set_up_register is a memory mapped specific register with the
following fields:
- RCMD (Read command, which is actually the flash read command)
- NUmber of Address bytes
- Number of dummy bytes
- Read type(Single, dual and quad read).
- Write command.
>> Once, the qspi controller is configured for a memory mapped read, the qspi
>> controller does not depend on the flash command that comes from the
>> mtd layer.
>> Because, this command are already configured in QSPI set up register.
> So this does depend on the flash commands for the specific chip, which
> means that this has all the same problems as the Freescale chip had with
> requiring the user to replicate the information about the commands that
> the chip supports into the device tree.  It therefore seems like all the
> same concerns should apply, though in this case it seems like it's
> harder for the driver to infer things from looking at the operations
> being sent to it.
>
> Presumably this also only works for flash chips, or things that look
> like them...
>
Yes, true, it depends on flash command, though it is getting filled now in
my driver itself.
>> Basically, its not the commands which need to be communicated from
>> the mtd layer,its just
>> the buffer to fill, len of buffer, offset from where to fill need to
>> be communicated.
> This appears to be based on an assumption that the commands would be
> replicated into the device trees which seems like it's both more work
> for users and harder to deploy.
>
>>> I'm also concerned about the interface here, it looks like this is being
>>> made visible to SPI devices (via a dependency on patch 3/3...) but only
>>> as a flag they can set - how would devices know to enable this and why
>>> would they want to avoid it?
>> Set  spi->mode in qspi driver based on dt entry and use that in mtd layer to
>> decide whether to use memory mapped or not.
> But why would anything not want to use memory mapped mode if it can and
> why is this something that should be hard coded into the device tree?
> Especially with the current API...
>
Thats true, by default also we can keep the memory mapped read. Though, 
according
to the current implementation spi->mode can be set so that in mtd layer, 
we might
use that to selectively used t[o].memory_map.
>> The idea is whenever, we call mtd_read api from mtd layer, if memory
>> mapped is set
>> then sending the commands does not matter, what matters is the len
>> to read, buffer to fill and
>> "from" offset to read. Then, the intention was to use the memory_map
>> transfer parameter to
>> communicate to the driver that memory mapped read is used so that we
>> can just use memcopy and
>> return without going through the entire SPI based xfer function.
> I'm not convinced that this is the most useful API, it sounds like the
> hardware can "memory map" the entire flash chip so the whole SPI
> framework seems like overhead.
>
But this memory map read will work only with read opcodes.(mtd_read
path). For all other operations, normal SPI operations will be used.

As for this, I also though of bypassing the SPI frameowrk, and doing a 
memcopy
at the beginning of the mtd_read api. But, then before doing a memory mapped
read -
1. Controller need to be switched to memory mapped port using control module
      register and ti qspi switch register.
2. There is SOC specific memory mapped address space from where read 
should happen,
     this is SOC specific and should be known to mtd layer the adreess 
to read for.
So, I thought of going this way using t.memory map flag.
> It also seems seems like it's going to involve the CPU being stalled
> waiting for reads to complete instead of asking the SPI controller to
> DMA the data to RAM and allowing the CPU to get on with other things -
> replacing the explicit transmission of commands with memory to memory
> DMAs might be advantageous but replacing DMA with memcpy() would need
> numbers to show that it was a win.



From broonie at kernel.org  Wed Oct  9 14:41:39 2013
From: broonie at kernel.org (Mark Brown)
Date: Wed, 9 Oct 2013 19:41:39 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <52559D52.4010400@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk> <52559D52.4010400@ti.com>
Message-ID: <20131009184139.GZ21581@sirena.org.uk>

On Wed, Oct 09, 2013 at 11:45:46PM +0530, Sourav Poddar wrote:
> On Wednesday 09 October 2013 11:10 PM, Mark Brown wrote:

> >I'm not convinced that this is the most useful API, it sounds like the
> >hardware can "memory map" the entire flash chip so the whole SPI
> >framework seems like overhead.

> But this memory map read will work only with read opcodes.(mtd_read
> path). For all other operations, normal SPI operations will be used.

> As for this, I also though of bypassing the SPI frameowrk, and doing
> a memcopy
> at the beginning of the mtd_read api. But, then before doing a memory mapped
> read -
> 1. Controller need to be switched to memory mapped port using control module
>      register and ti qspi switch register.
> 2. There is SOC specific memory mapped address space from where read
> should happen,
>     this is SOC specific and should be known to mtd layer the
> adreess to read for.
> So, I thought of going this way using t.memory map flag.

Sure, but these things sound like we should be able to support them
without having to bounce over to the SPI thread all the time and...

> >It also seems seems like it's going to involve the CPU being stalled
> >waiting for reads to complete instead of asking the SPI controller to
> >DMA the data to RAM and allowing the CPU to get on with other things -
> >replacing the explicit transmission of commands with memory to memory
> >DMAs might be advantageous but replacing DMA with memcpy() would need
> >numbers to show that it was a win.

...like I say it's not clear to me that this is actually a change that's
going to be beneficial.  I'd really like to see some analysis of the
performance showing that this helps and why it helps.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/601620c4/attachment.sig>

From richard.weinberger at gmail.com  Wed Oct  9 14:47:42 2013
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Wed, 9 Oct 2013 20:47:42 +0200
Subject: Grow UBI device?
In-Reply-To: <alpine.DEB.2.00.1310091725590.28562@lnxricardw.se.axis.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
 <20131009150538.BAD57380432@gemini.denx.de>
 <alpine.DEB.2.00.1310091725590.28562@lnxricardw.se.axis.com>
Message-ID: <CAFLxGvxMW+r=tHW_f7ugfrseBjbDZcL49-+KXo9S8E42WX1JMQ@mail.gmail.com>

On Wed, Oct 9, 2013 at 5:45 PM, Ricard Wanderlof
<ricard.wanderlof at axis.com> wrote:
>
> On Wed, 9 Oct 2013, Wolfgang Denk wrote:
>
>>>> Come to think of it, I'm not sure that would work anyway, as the
>>>> resulting, new, enlarged partition would partly contain UBI data and
>>>> partly old jffs2 data. I'm not sure what UBI does when it encounters
>>>> incorrect data, if it just erases the relevant blocks and formats them
>>>> for
>>>> its own use, or if it barfs completely and just bails out complaining
>>>> that
>>>> the partition does not contain UBI data. If the relevant blocks were
>>>> erased, then I think UBI would simply concede that the a previous erase
>>>> attempt had been prematurely aborted, and re-erase the blocks and write
>>>> its headers, so perhaps that is something to try. At any rate it
>>>> involves
>>>> at least some mild trickery (erase the blocks that previously contained
>>>> jffs2 data).
>>>>
>>> Yes, during mounting of UBIFS volumes, UBI checks for erase-header
>>> on first-page of every block.
>>
>>
>> Mounting UBIFS volumes should not be a problem - the existing ones are
>> not located in the newly added area of the NAND.  The question however
>> is what the UBI layer itself does, if I for example try to create a
>> new volume which then would allocate blocks from the newly added
>> space.
>
>
> UBI scans the whole partition when the attachement is made to the mtd
> partition. So if you'd get any error message regarding blocks that lack UBI
> headers it would be then, not when you subsequently try to create a volume
> in the partition. By that time the volume should be "formatted" with valid
> UBI headers.
>
>
>>> So, effectively you don't even need to erase the partition to convert
>>> it into UBI volume, you just try attaching it as UBI volume and UBI
>>> should erase it for you. (though flagging some warnings on the way).
>>
>>
>> Are you sure about that?
>>
>> Well, I guess I'll have to try it out in the end...
>
>
> I just tested it since I have a UBI system just beside me, by erasing and
> then writing zeros to a block (just to put non-UBI data in it) and
> restarting the system (the partition in question contains the volume with
> the root file system in it, so it is attached by the kernel during its
> boot). The result was that UBI didn't give any error or warning messages
> during boot, but a subsequent nanddump after boot revealed that the zeroed
> blocks now contained valid UBI headers, so, without looking at the source,
> it seems that UBI really does manage this fairly silently.

I've never tested this. But from my understanding of the UBI source
this behavior is
correct and intended. (Of course only in the non-fastmap case).

-- 
Thanks,
//richard


From peter at korsgaard.com  Wed Oct  9 15:01:59 2013
From: peter at korsgaard.com (Peter Korsgaard)
Date: Wed, 09 Oct 2013 21:01:59 +0200
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131009174027.GS21581@sirena.org.uk> (Mark Brown's message of
 "Wed, 9 Oct 2013 18:40:27 +0100")
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>
Message-ID: <87hacq1d5k.fsf@dell.be.48ers.dk>

>>>>> "Mark" == Mark Brown <broonie at kernel.org> writes:

Hi,

 Mark> I'm not convinced that this is the most useful API, it sounds like the
 Mark> hardware can "memory map" the entire flash chip so the whole SPI
 Mark> framework seems like overhead.

 Mark> It also seems seems like it's going to involve the CPU being
 Mark> stalled waiting for reads to complete instead of asking the SPI
 Mark> controller to DMA the data to RAM and allowing the CPU to get on
 Mark> with other things - replacing the explicit transmission of
 Mark> commands with memory to memory DMAs might be advantageous but
 Mark> replacing DMA with memcpy() would need numbers to show that it
 Mark> was a win.

Indeed. I can see how such a feature could be useful in E.G. a lowlevel
bootloader (because of simplicity), but am less convinced about it in
Linux where we could conceivable do something else useful while waiting
on the spi controller.

But if there's number to prove otherwise..

-- 
Bye, Peter Korsgaard


From broonie at kernel.org  Wed Oct  9 15:36:47 2013
From: broonie at kernel.org (Mark Brown)
Date: Wed, 9 Oct 2013 20:36:47 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <87hacq1d5k.fsf@dell.be.48ers.dk>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>
 <87hacq1d5k.fsf@dell.be.48ers.dk>
Message-ID: <20131009193647.GA21581@sirena.org.uk>

On Wed, Oct 09, 2013 at 09:01:59PM +0200, Peter Korsgaard wrote:

> Indeed. I can see how such a feature could be useful in E.G. a lowlevel
> bootloader (because of simplicity), but am less convinced about it in
> Linux where we could conceivable do something else useful while waiting
> on the spi controller.

> But if there's number to prove otherwise..

I can see it being useful if there's a DMA controller that can do the
transfer as a memory to memory DMA - the hardware can probably issue
flash read commands a bit faster than the AP can so you should be able
to get closer to saturating the bus.  The patches didn't try to do that
or make it possible for something further up the stack to do it and the
differences should end up being fairly small with optimisations like
those in the pxa2xx or pl022 drivers (which I'm currently working on
pulling out into the framework).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131009/8eb9c602/attachment.sig>

From wd at denx.de  Wed Oct  9 16:01:41 2013
From: wd at denx.de (Wolfgang Denk)
Date: Wed, 09 Oct 2013 22:01:41 +0200
Subject: Grow UBI device?
In-Reply-To: <alpine.DEB.2.00.1310091725590.28562@lnxricardw.se.axis.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
 <20131009150538.BAD57380432@gemini.denx.de>
 <alpine.DEB.2.00.1310091725590.28562@lnxricardw.se.axis.com>
Message-ID: <20131009200141.727C438049B@gemini.denx.de>

Dear Ricard,

In message <alpine.DEB.2.00.1310091725590.28562 at lnxricardw.se.axis.com> you wrote:
> 
> I just tested it since I have a UBI system just beside me, by erasing and 
> then writing zeros to a block (just to put non-UBI data in it) and 
> restarting the system (the partition in question contains the volume with 
> the root file system in it, so it is attached by the kernel during its 
> boot). The result was that UBI didn't give any error or warning messages 
> during boot, but a subsequent nanddump after boot revealed that the 
> zeroed blocks now contained valid UBI headers, so, without looking at the 
> source, it seems that UBI really does manage this fairly silently.

Thanks a lot, much appreciated!

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The IQ of the group is the lowest IQ of a member of the group divided
by the number of people in the group.


From computersforpeace at gmail.com  Wed Oct  9 17:44:01 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 14:44:01 -0700
Subject: N25Q256A 13E40
In-Reply-To: <201310091214.02740.marex@denx.de>
References: <201310071824.01028.marex@denx.de>
 <CAN8TOE_C+uU+JXn2OJ_5y6DbvxQXTQK7emEqoxXkCHkCzSQ13g@mail.gmail.com>
 <201310091214.02740.marex@denx.de>
Message-ID: <20131009214401.GD23337@ld-irv-0074.broadcom.com>

Hi,

On Wed, Oct 09, 2013 at 12:14:02PM +0200, Marek Vasut wrote:
> > On Mon, Oct 7, 2013 at 9:24 AM, Marek Vasut <marex at denx.de> wrote:
> > > Let's talk about our favourite chip :) I just got my hands on N25Q256A .
> > > Since there was quite a flurry of patches for this and similar chips and
> > > I got it working on a different chip with exactly the same IDs and type,
> > > I'd would expect linux to work with this one too. Guess what ... ;-)
> > > 
> > > This particular incarnation of N25Q256A completely ignores the 4-byte
> > > ERASE (0xdc) command. Apparently, if I look closely, it's N25Q256A 13E40
> > > variant and seeing the Note #14 (datasheet page 30 / below Table 18.
> > > Command set), quoting:
> > > 
> > > 14.This command is only for part numbers N25Q256A83ESF40x and
> > > N25Q256A83E1240x.
> > 
> > This note also applies to PAGE_PROGRAM_4B (0x12) as well, right?
> 
> Yeah, both ERASE_4B and PP_4B or whatever they're called there. Interestingly 
> enough, READ_4B works ;-/

Well, the READ_4B consistency is (unintentionally?) helpful for my
systems, as we have begun implementing a jumper switch so that the boot
ROM will know whether to use FAST_READ or FAST_READ_4B. Since
essentially all large SPI flash at *least* support the READ_4B command
(as you noted), we can reliably boot from the flash, no matter what mode
it is left in. After booting, we can choose the appropriate mode for
programming/erasing.

> > [Now that I went back to look at some more code:] Wait, but we don't
> > even try to use the 4-byte dedicated commands like 0xdc on Micron
> > flash, so why are you having this problem? The code currently stands
> > as:
> 
> The JEDEC_MFR for this flash Micron N25Q256A is CFI_MFR_ST (I wonder why).

Probably some series of acquisitions?

But you didn't quite answer my question. Are you having problems with
this Micron/ST/something-that's-not-AMD-or-Spansion flash using the
current mainline? Or did you only have trouble when you tried modifying
the code to use the dedicated 4-byte addressing commands?

> >   if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
> >           /* Dedicated 4-byte command set */
> >           ...

Brian


From ezequiel.garcia at free-electrons.com  Wed Oct  9 18:32:09 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 9 Oct 2013 19:32:09 -0300
Subject: [PATCH/TRIVIAL] mtd: Use MTD_BLOCK_MAJOR instead of the magic
 number
In-Reply-To: <CAN8TOE84raS7thT5ZU1Zpa7SQO7ocmmOdhrR7KxohQVsJix3Pg@mail.gmail.com>
References: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAN8TOE-9XRW9QJ7+sSis+Omo0eVAGVHOXD70P4L8FNbLut=9Dg@mail.gmail.com>
 <20131009120221.GB31294@localhost>
 <CAN8TOE84raS7thT5ZU1Zpa7SQO7ocmmOdhrR7KxohQVsJix3Pg@mail.gmail.com>
Message-ID: <20131009223208.GA2449@localhost>

On Wed, Oct 09, 2013 at 10:06:49AM -0700, Brian Norris wrote:
> On Wed, Oct 9, 2013 at 5:02 AM, Ezequiel Garcia
> <ezequiel.garcia at free-electrons.com> wrote:
> > On Tue, Oct 08, 2013 at 06:15:21PM -0700, Brian Norris wrote:
> >> Why does MTD_BLOCK_MAJOR (and MTD_CHAR_MAJOR) live in
> >> include/linux/mtd/mtd.h and not include/uapi/linux/major.h?
> >
> > Ah, nice catch. How about something like this?
> >
> > diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
> > index f9bfe52..9e1471e 100644
> > --- a/include/linux/mtd/mtd.h
> > +++ b/include/linux/mtd/mtd.h
> > @@ -24,14 +24,12 @@
> >  #include <linux/uio.h>
> >  #include <linux/notifier.h>
> >  #include <linux/device.h>
> > +#include <linux/major.h>
> 
> I think it's a (weak?) style preference that this type of #include
> just go in the files that need it (there are only a few -- 4 I think?)
> rather than importing it directly into the mtd.h header for all users.
> But I don't object strongly.
> 

Right. I thought that it would be best (as in less intrusive?) to match
the current behavior: mtd.h contains the major number definitions.
However, I also prefer to see headers included where they're used, so
let me fix a patch and let's see how that works.

> >  #include <mtd/mtd-abi.h>
> >
> >  #include <asm/div64.h>
> >
> > -#define MTD_CHAR_MAJOR 90
> > -#define MTD_BLOCK_MAJOR 31
> > -
> >  #define MTD_ERASE_PENDING      0x01
> >  #define MTD_ERASING            0x02
> >  #define MTD_ERASE_SUSPEND      0x04
> > diff --git a/include/uapi/linux/major.h b/include/uapi/linux/major.h
> > index 6a8ca98..620252e 100644
> > --- a/include/uapi/linux/major.h
> > +++ b/include/uapi/linux/major.h
> > @@ -54,6 +54,7 @@
> >  #define ACSI_MAJOR             28
> >  #define AZTECH_CDROM_MAJOR     29
> >  #define FB_MAJOR               29   /* /dev/fb* framebuffers */
> > +#define MTD_BLOCK_MAJOR                31
> >  #define CM206_CDROM_MAJOR      32
> >  #define IDE2_MAJOR             33
> >  #define IDE3_MAJOR             34
> > @@ -105,6 +106,7 @@
> >  #define IDE6_MAJOR             88
> >  #define IDE7_MAJOR             89
> >  #define IDE8_MAJOR             90
> > +#define MTD_CHAR_MAJOR         90
> >  #define IDE9_MAJOR             91
> >
> >  #define DASD_MAJOR             94
> >
> > --
> >
> > If you think this is OK, you can take this patch and I'll cook
> > another one moving MTD_xxx_MAJOR as above.
> 
> Yeah, the original patch here is good. I'll run it through the build
> tests and then apply it. Feel free to send a proper follow-up with
> either the diff you just sent or with the #include <linux/major.h>
> moved into the appropriate .c files.
> 

Ok.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Wed Oct  9 20:48:05 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 17:48:05 -0700
Subject: [PATCH/TRIVIAL] mtd: Use MTD_BLOCK_MAJOR instead of the magic
 number
In-Reply-To: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1381276748-5426-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131010004805.GE23337@ld-irv-0074.broadcom.com>

On Tue, Oct 08, 2013 at 08:59:08PM -0300, Ezequiel Garcia wrote:
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/mtdblock.c    | 2 +-
>  drivers/mtd/mtdblock_ro.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
> index 2aef5dd..53884cc 100644
> --- a/drivers/mtd/mtdblock.c
> +++ b/drivers/mtd/mtdblock.c
> @@ -373,7 +373,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
>  
>  static struct mtd_blktrans_ops mtdblock_tr = {
>  	.name		= "mtdblock",
> -	.major		= 31,
> +	.major		= MTD_BLOCK_MAJOR,
>  	.part_bits	= 0,
>  	.blksize 	= 512,
>  	.open		= mtdblock_open,
> diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
> index 92759a9..70d27b4 100644
> --- a/drivers/mtd/mtdblock_ro.c
> +++ b/drivers/mtd/mtdblock_ro.c
> @@ -70,7 +70,7 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
>  
>  static struct mtd_blktrans_ops mtdblock_tr = {
>  	.name		= "mtdblock",
> -	.major		= 31,
> +	.major		= MTD_BLOCK_MAJOR,
>  	.part_bits	= 0,
>  	.blksize 	= 512,
>  	.readsect	= mtdblock_readsect,

Pushed to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Wed Oct  9 20:49:56 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 17:49:56 -0700
Subject: [PATCH 1/2] mtd: sst25l: Remove redundant spi_set_drvdata
In-Reply-To: <1381224094-14098-1-git-send-email-sachin.kamat@linaro.org>
References: <1381224094-14098-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131010004956.GF23337@ld-irv-0074.broadcom.com>

On Tue, Oct 08, 2013 at 02:51:33PM +0530, Sachin Kamat wrote:
> Driver core will set the driver data to NULL upon detach
> or probe failure.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Pushed the pair to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Wed Oct  9 20:50:29 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 17:50:29 -0700
Subject: [PATCH 1/2] mtd: fsl_ifc_nand: Remove redundant dev_set_drvdata
In-Reply-To: <1381225100-19693-1-git-send-email-sachin.kamat@linaro.org>
References: <1381225100-19693-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131010005029.GG23337@ld-irv-0074.broadcom.com>

On Tue, Oct 08, 2013 at 03:08:19PM +0530, Sachin Kamat wrote:
> Driver core will set the driver data to NULL upon detach or
> probe failure.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Pushed both to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Wed Oct  9 20:51:11 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 17:51:11 -0700
Subject: [PATCH 1/2] mtd: socrates_nand: Remove redundant dev_set_drvdata
In-Reply-To: <1381226506-23030-1-git-send-email-sachin.kamat@linaro.org>
References: <1381226506-23030-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131010005111.GH23337@ld-irv-0074.broadcom.com>

On Tue, Oct 08, 2013 at 03:31:45PM +0530, Sachin Kamat wrote:
> Driver core will set the driver data to NULL upon detach or
> probe failure.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Pushed both to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Wed Oct  9 20:51:31 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 9 Oct 2013 17:51:31 -0700
Subject: [PATCH 1/1] mtd: socrates_nand: Use dev_err instead of printk
In-Reply-To: <1381226888-23901-1-git-send-email-sachin.kamat@linaro.org>
References: <1381226888-23901-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131010005131.GI23337@ld-irv-0074.broadcom.com>

On Tue, Oct 08, 2013 at 03:38:08PM +0530, Sachin Kamat wrote:
> dev_err is preferred to printk.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Pushed to l2-mtd.git. Thanks!

Brian


From tpiepho at gmail.com  Wed Oct  9 22:27:11 2013
From: tpiepho at gmail.com (Trent Piepho)
Date: Wed, 9 Oct 2013 19:27:11 -0700
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <87hacq1d5k.fsf@dell.be.48ers.dk>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>
 <87hacq1d5k.fsf@dell.be.48ers.dk>
Message-ID: <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>

On Wed, Oct 9, 2013 at 12:01 PM, Peter Korsgaard <peter at korsgaard.com> wrote:
>>>>>> "Mark" == Mark Brown <broonie at kernel.org> writes:
>  Mark> I'm not convinced that this is the most useful API, it sounds like the
>  Mark> hardware can "memory map" the entire flash chip so the whole SPI
>  Mark> framework seems like overhead.
>
>  Mark> It also seems seems like it's going to involve the CPU being
>  Mark> stalled waiting for reads to complete instead of asking the SPI
>  Mark> controller to DMA the data to RAM and allowing the CPU to get on
>  Mark> with other things - replacing the explicit transmission of
>  Mark> commands with memory to memory DMAs might be advantageous but
>  Mark> replacing DMA with memcpy() would need numbers to show that it
>  Mark> was a win.
>
> Indeed. I can see how such a feature could be useful in E.G. a lowlevel
> bootloader (because of simplicity), but am less convinced about it in
> Linux where we could conceivable do something else useful while waiting
> on the spi controller.

I've found that the SPI layer adds rather a lot of overhead to SPI
transactions.  It appears to come mostly from using another thread to
run the queue.  A fast SPI message of a few dozen bytes ends up having
more overhead from the SPI layer than the time it takes the driver to
do the actual transfer.

So memory mapped mode via some kind of SPI hack seems like a bad
design.  All the SPI layer overhead and you don't get DMA.  Memory
mapped SPI could be a win, but I think you'd need to do it at the MTD
layer with a mapping driver that could read the mmapped SPI flash
directly.


From dedekind1 at gmail.com  Thu Oct 10 03:42:42 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 10 Oct 2013 10:42:42 +0300
Subject: Grow UBI device?
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <alpine.DEB.2.00.1310091038110.28562@lnxricardw.se.axis.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA20350@DBDE04.ent.ti.com>
Message-ID: <1381390962.7875.57.camel@sauron.fi.intel.com>

On Wed, 2013-10-09 at 11:28 +0000, Gupta, Pekon wrote:
> Yes, during mounting of UBIFS volumes, UBI checks for erase-header
> on first-page of every block. 
> - If it's able to find a valid erase-header, with correct image_seq field,
> then it attaches it to its pool.
> - Otherwise, if the valid erase-header was not found, then it assumes
>  then it ubi will try re-erasing it. And add it to its pool of free-blocks.

I think there is a separate list for blocks with garbage, and if UBI
finds too much of them, it attaches R/O. So if it would find too many
JFFS2 eraseblocks, it would not erase them. But erasing the JFFS2 blocks
from outside of UBI driver would help.

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Thu Oct 10 04:17:18 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Thu, 10 Oct 2013 11:17:18 +0300
Subject: Grow UBI device?
In-Reply-To: <20131008192846.A25E7380A65@gemini.denx.de>
References: <20131008192846.A25E7380A65@gemini.denx.de>
Message-ID: <1381393038.7875.83.camel@sauron.fi.intel.com>

Wolfgang, people already answered you, and frankly I did not read all
the answers :-) But here is my brief version.

On Tue, 2013-10-08 at 21:28 +0200, Wolfgang Denk wrote:
> I'm looking for a clever way to migrate devices (in the field) from
> JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
> device (which covers the whole NAND chip) with several volumes used
> with UBIFS.  Unfortunately I must keep some of the existing data.

And I guess there is no temporary storage where you could copy JFFS2
files, re-format the flash, and copy the files back.

> It would be nice if I could start with a UBI device that is smaller
> than the NAND, so I can keep an existing MTD partition with a JFFS2
> file system.

You mean that on the existing systems, you already have an extra MTD
partition, or you somehow can create one.

Then you want to UBI/UBIFS-format the extra partition. Then copy
required JFFS2 files there. And then kill JFFS2 partitions and "merge"
them with the extra partition, and end up with UBI/UBIFS covering all
the space.

>  After copying the data from JFFS2 to a UBIFS volume, I
> would like to free and reuse the space of this JFFS2 partition.

OK, sounds like I understood you correctly.

> Is there a way to "grow" the existing UBI device so that it now also
> covers the rest of the NAND chip?  Or is my only option to create a
> second UBI device?

I think so, unless you use the fastmap feature. Suppose you don't.

There are 2 parts - UBI and UBIFS.

So, let's suppose your situation is like this.

1. You have 2 mtd partitions - mtd1 and mtd2.
2. mtd1 has JFFS2 with important files.
3. mtd2 is the extra partition you have.

I guess you can do this.

1. Format mtd2 with UBI. Just erasing should be OK, or you can use
ubiformat: http://www.linux-mtd.infradead.org/faq/ubi.html#L_ubierase

Then you attach mtd2 (ubiattach) and you get an UBI device (/dev/ubiX).

2. Create a volume on /dev/ubiX which spans entire UBI device
(ubimkvol -t AFAIR). You end up with UBI volume /dev/ubiX_0.

3. And here is important part - you format /dev/ubiX_0 with JFFS2 but
correctly.

UBIFS has this "automatic expand" feature. Which means that if the UBI
volume underneath it becomes larger, UBIFS will expand automatically and
take the entire (larger) UBI volume.

However, there is a _limit_ to how much UBIFS can expand from the
original size. And you want to watch this limit and make it big enough.

The limit is connected with the "-c" option of mkfs.ubifs. Please, check
the docs - they explain what exactly -c controls and how it is related
to the maximum UBIFS file-system size:

http://www.linux-mtd.infradead.org/faq/ubifs.html#L_max_leb_cnt

So, select proper -c.

If you do not use mkfs.ubifs, but just attach /dev/ubiX_0, the UBIFS
kernel driver will format the volume automatically. It will select the
-c value itself. Since this value is power of 2, it will just take the
smallest power-of-2 value. It may be OK for your purposes, may be not.
It is safer to use mkfs.ubifs with explicit -c.

Basically this is the trickiest part, rest _should_ be easy, but you'll
learn when you try :-)

4. Copy important files from JFFS2-mtd1 to UBIFS-UBI-mtd2.

5. Erase mtd1 (or you can do this later too)

6. I do not know how you do this, but kill mtd1, and resize mtd2.
Probably mtd2 will then be named mtd1 after reboot. If you always refer
your MTD partitions and UBI volumes by name, you should not suffer to
much from mtd2 becoming mtd1.

Lets suppose there is no rename, for simplicity.

7. Make sure former JFFS2-mtd1 eraseblocks are erased (unless you did
this at step 5).

8. Attach mtd2 to UBI. UBI will automatically "take" the new
eraseblocks, erase them and write UBI headers there, and make available.

9. Volume size will still be the same, and you need to re-size it using
ubiresize.

10. Mount the resized volume. UBI will enlarge itself.

Problem solved.

Surely you do not want power cuts during this operations. If you need to
survive power cuts, I guess it is possible, but more complex.

HTH.

-- 
Best Regards,
Artem Bityutskiy



From richard.weinberger at gmail.com  Thu Oct 10 04:34:44 2013
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Thu, 10 Oct 2013 10:34:44 +0200
Subject: Grow UBI device?
In-Reply-To: <1381393038.7875.83.camel@sauron.fi.intel.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <1381393038.7875.83.camel@sauron.fi.intel.com>
Message-ID: <CAFLxGvz6=5FxQ8oeDfm1OYhJGfLkwJkuBh315-WBDLNc6bmF6A@mail.gmail.com>

On Thu, Oct 10, 2013 at 10:17 AM, Artem Bityutskiy <dedekind1 at gmail.com> wrote:
> Wolfgang, people already answered you, and frankly I did not read all
> the answers :-) But here is my brief version.
>
> On Tue, 2013-10-08 at 21:28 +0200, Wolfgang Denk wrote:
>> I'm looking for a clever way to migrate devices (in the field) from
>> JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
>> device (which covers the whole NAND chip) with several volumes used
>> with UBIFS.  Unfortunately I must keep some of the existing data.
>
> And I guess there is no temporary storage where you could copy JFFS2
> files, re-format the flash, and copy the files back.
>
>> It would be nice if I could start with a UBI device that is smaller
>> than the NAND, so I can keep an existing MTD partition with a JFFS2
>> file system.
>
> You mean that on the existing systems, you already have an extra MTD
> partition, or you somehow can create one.
>
> Then you want to UBI/UBIFS-format the extra partition. Then copy
> required JFFS2 files there. And then kill JFFS2 partitions and "merge"
> them with the extra partition, and end up with UBI/UBIFS covering all
> the space.
>
>>  After copying the data from JFFS2 to a UBIFS volume, I
>> would like to free and reuse the space of this JFFS2 partition.
>
> OK, sounds like I understood you correctly.
>
>> Is there a way to "grow" the existing UBI device so that it now also
>> covers the rest of the NAND chip?  Or is my only option to create a
>> second UBI device?
>
> I think so, unless you use the fastmap feature. Suppose you don't.
>
> There are 2 parts - UBI and UBIFS.
>
> So, let's suppose your situation is like this.
>
> 1. You have 2 mtd partitions - mtd1 and mtd2.
> 2. mtd1 has JFFS2 with important files.
> 3. mtd2 is the extra partition you have.
>
> I guess you can do this.
>
> 1. Format mtd2 with UBI. Just erasing should be OK, or you can use
> ubiformat: http://www.linux-mtd.infradead.org/faq/ubi.html#L_ubierase
>
> Then you attach mtd2 (ubiattach) and you get an UBI device (/dev/ubiX).
>
> 2. Create a volume on /dev/ubiX which spans entire UBI device
> (ubimkvol -t AFAIR). You end up with UBI volume /dev/ubiX_0.
>
> 3. And here is important part - you format /dev/ubiX_0 with JFFS2 but
> correctly.

s/JFFS2/UBIFS :-)

> UBIFS has this "automatic expand" feature. Which means that if the UBI
> volume underneath it becomes larger, UBIFS will expand automatically and
> take the entire (larger) UBI volume.
>
> However, there is a _limit_ to how much UBIFS can expand from the
> original size. And you want to watch this limit and make it big enough.
>
> The limit is connected with the "-c" option of mkfs.ubifs. Please, check
> the docs - they explain what exactly -c controls and how it is related
> to the maximum UBIFS file-system size:
>
> http://www.linux-mtd.infradead.org/faq/ubifs.html#L_max_leb_cnt
>
> So, select proper -c.
>
> If you do not use mkfs.ubifs, but just attach /dev/ubiX_0, the UBIFS
> kernel driver will format the volume automatically. It will select the
> -c value itself. Since this value is power of 2, it will just take the
> smallest power-of-2 value. It may be OK for your purposes, may be not.
> It is safer to use mkfs.ubifs with explicit -c.
>
> Basically this is the trickiest part, rest _should_ be easy, but you'll
> learn when you try :-)
>
> 4. Copy important files from JFFS2-mtd1 to UBIFS-UBI-mtd2.
>
> 5. Erase mtd1 (or you can do this later too)
>
> 6. I do not know how you do this, but kill mtd1, and resize mtd2.
> Probably mtd2 will then be named mtd1 after reboot. If you always refer
> your MTD partitions and UBI volumes by name, you should not suffer to
> much from mtd2 becoming mtd1.
>
> Lets suppose there is no rename, for simplicity.
>
> 7. Make sure former JFFS2-mtd1 eraseblocks are erased (unless you did
> this at step 5).
>
> 8. Attach mtd2 to UBI. UBI will automatically "take" the new
> eraseblocks, erase them and write UBI headers there, and make available.
>
> 9. Volume size will still be the same, and you need to re-size it using
> ubiresize.
>
> 10. Mount the resized volume. UBI will enlarge itself.
>
> Problem solved.
>
> Surely you do not want power cuts during this operations. If you need to
> survive power cuts, I guess it is possible, but more complex.
>
> HTH.
>
> --
> Best Regards,
> Artem Bityutskiy
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



-- 
Thanks,
//richard


From sourav.poddar at ti.com  Thu Oct 10 04:52:28 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 10 Oct 2013 14:22:28 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>	<1381332284-21822-2-git-send-email-sourav.poddar@ti.com>	<20131009160759.GQ21581@sirena.org.uk>	<52558A49.5090904@ti.com>	<20131009174027.GS21581@sirena.org.uk>	<87hacq1d5k.fsf@dell.be.48ers.dk>
 <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>
Message-ID: <52566ACC.1080100@ti.com>

Hi All,
On Thursday 10 October 2013 07:57 AM, Trent Piepho wrote:
> On Wed, Oct 9, 2013 at 12:01 PM, Peter Korsgaard<peter at korsgaard.com>  wrote:
>>>>>>> "Mark" == Mark Brown<broonie at kernel.org>  writes:
>>   Mark>  I'm not convinced that this is the most useful API, it sounds like the
>>   Mark>  hardware can "memory map" the entire flash chip so the whole SPI
>>   Mark>  framework seems like overhead.
>>
>>   Mark>  It also seems seems like it's going to involve the CPU being
>>   Mark>  stalled waiting for reads to complete instead of asking the SPI
>>   Mark>  controller to DMA the data to RAM and allowing the CPU to get on
>>   Mark>  with other things - replacing the explicit transmission of
>>   Mark>  commands with memory to memory DMAs might be advantageous but
>>   Mark>  replacing DMA with memcpy() would need numbers to show that it
>>   Mark>  was a win.
>>
>> Indeed. I can see how such a feature could be useful in E.G. a lowlevel
>> bootloader (because of simplicity), but am less convinced about it in
>> Linux where we could conceivable do something else useful while waiting
>> on the spi controller.
> I've found that the SPI layer adds rather a lot of overhead to SPI
> transactions.  It appears to come mostly from using another thread to
> run the queue.  A fast SPI message of a few dozen bytes ends up having
> more overhead from the SPI layer than the time it takes the driver to
> do the actual transfer.
>
> So memory mapped mode via some kind of SPI hack seems like a bad
> design.  All the SPI layer overhead and you don't get DMA.  Memory
> mapped SPI could be a win, but I think you'd need to do it at the MTD
> layer with a mapping driver that could read the mmapped SPI flash
> directly.
Yes, you are correct in all your comments above. I also feel that SPI 
framework
should be bypassed. But the subject patch is derived based on the 
following points/limitation:

1. There is a setup register in QSPI, that need to be filled, as of now 
I am filling it
     in my driver as a MACRO.
2. Controller repsonds to memory mapped read for read opcodes, so during the
read path we should tell the controller to switch to memory mapped port.

[Trent]: With mapping driver, I believe you are hinting at 
drivers/mtd/maps? I had
a look at it and what I got is that it is used/suitable for parallel 
flashes and not the
serial flashes.

All in all, Just at the beginning of the read api, I could have done 
memory mapped read and bypass
the spi framework. But, prior to that above 1, 2 point need to be 
executed and that need to be
communicated to controller driver.


From broonie at kernel.org  Thu Oct 10 06:10:52 2013
From: broonie at kernel.org (Mark Brown)
Date: Thu, 10 Oct 2013 11:10:52 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>
 <87hacq1d5k.fsf@dell.be.48ers.dk>
 <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>
Message-ID: <20131010101052.GF21581@sirena.org.uk>

On Wed, Oct 09, 2013 at 07:27:11PM -0700, Trent Piepho wrote:

> I've found that the SPI layer adds rather a lot of overhead to SPI
> transactions.  It appears to come mostly from using another thread to
> run the queue.  A fast SPI message of a few dozen bytes ends up having
> more overhead from the SPI layer than the time it takes the driver to
> do the actual transfer.

Yeah, though of course at the minute the implementation of that thread
is pretty much up to the individual drivers which isn't triumph - and
the quality of implementation does vary rather a lot.  I'm currently
working on trying to factor more of this out, hopefully then it'll be
easier to push out improvements.  It may be nice to be able to kick off
the first DMA transfer from within the caller for example.

> So memory mapped mode via some kind of SPI hack seems like a bad
> design.  All the SPI layer overhead and you don't get DMA.  Memory
> mapped SPI could be a win, but I think you'd need to do it at the MTD
> layer with a mapping driver that could read the mmapped SPI flash
> directly.

Yes, exactly and even then I'm not convinced that it's going to be much
advantage for anything except small transfers without DMA.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131010/2a69a65a/attachment-0001.sig>

From broonie at kernel.org  Thu Oct 10 06:14:10 2013
From: broonie at kernel.org (Mark Brown)
Date: Thu, 10 Oct 2013 11:14:10 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <52566ACC.1080100@ti.com>
References: <52566ACC.1080100@ti.com>
Message-ID: <20131010101410.GG21581@sirena.org.uk>

On Thu, Oct 10, 2013 at 02:22:28PM +0530, Sourav Poddar wrote:

> [Trent]: With mapping driver, I believe you are hinting at
> drivers/mtd/maps? I had
> a look at it and what I got is that it is used/suitable for parallel
> flashes and not the
> serial flashes.

Essentially what it looks like this hardware is trying to do is adapt a
serial flash so it looks more like a parallel flash.  It's not clear
that this is a good idea if we are already able to understand serial
flash though.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131010/12f81c2d/attachment.sig>

From sourav.poddar at ti.com  Thu Oct 10 06:17:45 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 10 Oct 2013 15:47:45 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131010101410.GG21581@sirena.org.uk>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
Message-ID: <52567EC9.1020708@ti.com>

On Thursday 10 October 2013 03:44 PM, Mark Brown wrote:
> On Thu, Oct 10, 2013 at 02:22:28PM +0530, Sourav Poddar wrote:
>
>> [Trent]: With mapping driver, I believe you are hinting at
>> drivers/mtd/maps? I had
>> a look at it and what I got is that it is used/suitable for parallel
>> flashes and not the
>> serial flashes.
> Essentially what it looks like this hardware is trying to do is adapt a
> serial flash so it looks more like a parallel flash.  It's not clear
> that this is a good idea if we are already able to understand serial
> flash though.
hmm..
one more point I want to add is that QSPI controller has
two parts to it:
1. SPI mode (used for SPI based external devices)
2. SFI mode (Serial flash interface) used for flash devices attached.
     Memory mapped mode is the one more applicable to the second one.



From sourav.poddar at ti.com  Thu Oct 10 07:08:19 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 10 Oct 2013 16:38:19 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131010101410.GG21581@sirena.org.uk>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
Message-ID: <52568AA3.9080203@ti.com>

Hi Mark,
On Thursday 10 October 2013 03:44 PM, Mark Brown wrote:
> On Thu, Oct 10, 2013 at 02:22:28PM +0530, Sourav Poddar wrote:
>
>> [Trent]: With mapping driver, I believe you are hinting at
>> drivers/mtd/maps? I had
>> a look at it and what I got is that it is used/suitable for parallel
>> flashes and not the
>> serial flashes.
> Essentially what it looks like this hardware is trying to do is adapt a
> serial flash so it looks more like a parallel flash.  It's not clear
> that this is a good idea if we are already able to understand serial
> flash though.
Do you have any idea of how to go about implementing it in a more
cleaner way?(taking care of all what the spi controller hardware needs to
do for the memory mapped mode.). I understand doing a memcpy in the caller
itself, but how to tackle the spi controller configuration at that point 
of time.
Memory mapped is  a spi controller feature rather than a flash.


From mikedunn at newsguy.com  Thu Oct 10 13:25:27 2013
From: mikedunn at newsguy.com (Mike Dunn)
Date: Thu, 10 Oct 2013 10:25:27 -0700
Subject: [PATCH] [RESEND] mtd: docg4: fix status polling loop
Message-ID: <1381425927-1881-1-git-send-email-mikedunn@newsguy.com>

The loop that polls the status register waiting for an operation to complete
foolishly bases the timeout simply on the number of loop iterations that have
ocurred.  When I increased the processor clock speed, timeouts started to appear
for long block erasure operations.  This patch measures the timeout using
jiffies.

Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
---

This is a rework of an earlier patch, based on Artem's recommendation to use
jiffies, not udelay() (thanks Artem).  I didn't mark it 'v2' because the rework
makes the original name of the patch inaccurate, so now it has a different name.

This was originally sent a couple months ago... was probably a bad time.

 drivers/mtd/nand/docg4.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index fa25e7a..6c3be21 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -44,6 +44,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/bch.h>
 #include <linux/bitrev.h>
+#include <linux/jiffies.h>
 
 /*
  * In "reliable mode" consecutive 2k pages are used in parallel (in some
@@ -269,7 +270,7 @@ static int poll_status(struct docg4_priv *doc)
 	 */
 
 	uint16_t flash_status;
-	unsigned int timeo;
+	unsigned long timeo;
 	void __iomem *docptr = doc->virtadr;
 
 	dev_dbg(doc->dev, "%s...\n", __func__);
@@ -277,22 +278,18 @@ static int poll_status(struct docg4_priv *doc)
 	/* hardware quirk requires reading twice initially */
 	flash_status = readw(docptr + DOC_FLASHCONTROL);
 
-	timeo = 1000;
+	timeo = jiffies + msecs_to_jiffies(200); /* generous timeout */
 	do {
 		cpu_relax();
 		flash_status = readb(docptr + DOC_FLASHCONTROL);
-	} while (!(flash_status & DOC_CTRL_FLASHREADY) && --timeo);
+	} while (!(flash_status & DOC_CTRL_FLASHREADY) &&
+		 time_before(jiffies, timeo));
 
-
-	if (!timeo) {
+	if (unlikely(!(flash_status & DOC_CTRL_FLASHREADY))) {
 		dev_err(doc->dev, "%s: timed out!\n", __func__);
 		return NAND_STATUS_FAIL;
 	}
 
-	if (unlikely(timeo < 50))
-		dev_warn(doc->dev, "%s: nearly timed out; %d remaining\n",
-			 __func__, timeo);
-
 	return 0;
 }
 
-- 
1.8.1.5



From bootloader99 at yahoo.com  Thu Oct 10 14:12:12 2013
From: bootloader99 at yahoo.com (Flash K)
Date: Thu, 10 Oct 2013 11:12:12 -0700 (PDT)
Subject: lzari errors observed when accessing data from NAND Flash
In-Reply-To: <1381397050.60858.YahooMailNeo@web125601.mail.ne1.yahoo.com>
Message-ID: <1381428732.71524.YahooMailBasic@web125604.mail.ne1.yahoo.com>


 Hi,
 1. I am presently working on porting a 2.4 BSP
 to a 3.0. 
 2. The 2.4 based system uses the JFFS2 File system that
 supports LZARI compression. 
 3. Now the support for LZARI compression is not present in
 the 3.0 Kernel.
 4. However as some of the files on the Embedded system need
 to be retained 
 during the upgrade (from 2.4 to 3.0) we have explicitly
 added suppport for LZARI. 
 5. This includes modifying the kconfig file, adding the
 compr_lzari.c at the location fs\jffs2\ 
 and building the lzari support in the Kernel.
 After booting the Kernel, we see the following messages when
 trying to access files
 output of dmesg:
 [ 6480.539070] Error: jffs2_decompress returned -1
 [ 6480.543887] read_cache_page() returned error: -1
 [ 6480.548657] Error garbage collecting node at 010a5018!
 [ 6480.572338] Decompressor "lzari" returned -1
 [ 6480.577397] Error: jffs2_decompress returned -1
 [ 6480.582214] read_cache_page() returned error: -1
 [ 6480.586983] Error garbage collecting node at 010a5018!
 [ 6480.609512] Decompressor "lzari" returned -1
 [ 6480.614579] Error: jffs2_decompress returned -1
 [ 6480.619404] read_cache_page() returned error: -1
 [ 6480.624176] Error garbage collecting node at 010a5018!
 ?
 These errors are crashing the File system.
 Hardware Details: ARM iMX21 based processor, Micron
 NAND Flash
 ?
 I am presently trying to debug this. 
 Could somebody help in guiding me how to debug file system
 errors?
 I need to find the root cause and fix this. I have begun going through the jffs2 filesystem drivers but am not able to make significant progress.

 Regards,
 Flash
 
 


From torvalds at linux-foundation.org  Thu Oct 10 14:32:10 2013
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Thu, 10 Oct 2013 11:32:10 -0700
Subject: [GIT PULL] MTD fixes for 3.12-rc
In-Reply-To: <1381306577.9617.15.camel@shinybook.infradead.org>
References: <1381284622-24286-1-git-send-email-computersforpeace@gmail.com>
 <1381306577.9617.15.camel@shinybook.infradead.org>
Message-ID: <CA+55aFwxibkqx2imbGXRzjK_3-k5UiB4cqXOoF-JwXr9U-OmUw@mail.gmail.com>

On Wed, Oct 9, 2013 at 1:16 AM, David Woodhouse <dwmw2 at infradead.org> wrote:
>
> You should probably be signing your tags. Even if your key isn't in the
> strong set yet, at least they would consistently be signed with the
> *same* key.

Agreed. Even an unvalidated key is better than no key, since it can be
validated later, and even if never validated shows at least that
multiple pull requests were generated by people who had access to that
key..

              Linus


From weiyj.lk at gmail.com  Fri Oct 11 00:40:21 2013
From: weiyj.lk at gmail.com (Wei Yongjun)
Date: Fri, 11 Oct 2013 12:40:21 +0800
Subject: [PATCH] mtg: docg3: use free_bch() instead of kfree()
Message-ID: <CAPgLHd_vT4cJ1F1a6TDzYb2LFSb-me90K58K22Z=ae3VsOfbng@mail.gmail.com>

From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Use free_bch() instead of kfree() to free init_bch()
allocated data.

Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
---
 drivers/mtd/devices/docg3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 3e1b0a0..4f091c1 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -2097,7 +2097,7 @@ notfound:
 	ret = -ENODEV;
 	dev_info(dev, "No supported DiskOnChip found\n");
 err_probe:
-	kfree(cascade->bch);
+	free_bch(cascade->bch);
 	for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
 		if (cascade->floors[floor])
 			doc_release_device(cascade->floors[floor]);



From sachin.kamat at linaro.org  Fri Oct 11 00:41:25 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Fri, 11 Oct 2013 10:11:25 +0530
Subject: [PATCH 3/3] mtd: bcm47xxnflash: Use devm_kzalloc
In-Reply-To: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>
References: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1381466485-7534-3-git-send-email-sachin.kamat@linaro.org>

devm_kzalloc is device managed and simplifies the code.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/bcm47xxnflash/main.c |   18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c
index 2dc3aa6..1074459 100644
--- a/drivers/mtd/nand/bcm47xxnflash/main.c
+++ b/drivers/mtd/nand/bcm47xxnflash/main.c
@@ -29,11 +29,9 @@ static int bcm47xxnflash_probe(struct platform_device *pdev)
 	struct bcm47xxnflash *b47n;
 	int err = 0;
 
-	b47n = kzalloc(sizeof(*b47n), GFP_KERNEL);
-	if (!b47n) {
-		err = -ENOMEM;
-		goto out;
-	}
+	b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL);
+	if (!b47n)
+		return -ENOMEM;
 
 	b47n->nand_chip.priv = b47n;
 	b47n->mtd.owner = THIS_MODULE;
@@ -48,22 +46,16 @@ static int bcm47xxnflash_probe(struct platform_device *pdev)
 	}
 	if (err) {
 		pr_err("Initialization failed: %d\n", err);
-		goto err_init;
+		return err;
 	}
 
 	err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0);
 	if (err) {
 		pr_err("Failed to register MTD device: %d\n", err);
-		goto err_dev_reg;
+		return err;
 	}
 
 	return 0;
-
-err_dev_reg:
-err_init:
-	kfree(b47n);
-out:
-	return err;
 }
 
 static int bcm47xxnflash_remove(struct platform_device *pdev)
-- 
1.7.9.5



From sachin.kamat at linaro.org  Fri Oct 11 00:41:24 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Fri, 11 Oct 2013 10:11:24 +0530
Subject: [PATCH 2/3] mtd: bcm47xxnflash: Use module_platform_driver
In-Reply-To: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>
References: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <1381466485-7534-2-git-send-email-sachin.kamat@linaro.org>

module_platform_driver simplifies the code by removing boiler plate.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/bcm47xxnflash/main.c |   20 +-------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c
index 7bae569..2dc3aa6 100644
--- a/drivers/mtd/nand/bcm47xxnflash/main.c
+++ b/drivers/mtd/nand/bcm47xxnflash/main.c
@@ -85,22 +85,4 @@ static struct platform_driver bcm47xxnflash_driver = {
 	},
 };
 
-static int __init bcm47xxnflash_init(void)
-{
-	int err;
-
-	err = platform_driver_register(&bcm47xxnflash_driver);
-	if (err)
-		pr_err("Failed to register bcm47xx nand flash driver: %d\n",
-		       err);
-
-	return err;
-}
-
-static void __exit bcm47xxnflash_exit(void)
-{
-	platform_driver_unregister(&bcm47xxnflash_driver);
-}
-
-module_init(bcm47xxnflash_init);
-module_exit(bcm47xxnflash_exit);
+module_platform_driver(bcm47xxnflash_driver);
-- 
1.7.9.5



From sachin.kamat at linaro.org  Fri Oct 11 00:41:23 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Fri, 11 Oct 2013 10:11:23 +0530
Subject: [PATCH 1/3] mtd: plat-ram: Use module_platform_driver
Message-ID: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>

module_platform_driver simplifies the code by removing boiler
plate.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/maps/plat-ram.c |   16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index 3e35b9a..10196f5 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -257,21 +257,7 @@ static struct platform_driver platram_driver = {
 	},
 };
 
-/* module init/exit */
-
-static int __init platram_init(void)
-{
-	printk("Generic platform RAM MTD, (c) 2004 Simtec Electronics\n");
-	return platform_driver_register(&platram_driver);
-}
-
-static void __exit platram_exit(void)
-{
-	platform_driver_unregister(&platram_driver);
-}
-
-module_init(platram_init);
-module_exit(platram_exit);
+module_platform_driver(platram_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben at simtec.co.uk>");
-- 
1.7.9.5



From pekon at ti.com  Fri Oct 11 03:10:41 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 11 Oct 2013 07:10:41 +0000
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <CAD6G_RShZMkSpVzvXWEE0+sDX=pcnf7ndChndgDG5_T4EVL2vQ@mail.gmail.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
 <CAD6G_RShZMkSpVzvXWEE0+sDX=pcnf7ndChndgDG5_T4EVL2vQ@mail.gmail.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA21134@DBDE04.ent.ti.com>

Hi,

> From: Jagan Teki
> > Sourav Poddar <sourav.poddar at ti.com>
> > Some flash also support quad read mode.
> > Adding support for adding quad mode in m25p80
> > for spansion and macronix flash.
> 
> I am some how not happy with this approach, adding a flags on flash
> param table for supporting
> quad operation in specific flash is may be a better idea.
> 
> But reading SFDP, is a good idea to get the details of flash - quad
> support is one of them.
> and we can assign quad read or fast read based on that.
> 
> Any comments.
> 
Currently SFDP is mostly supported only on Micron devices, that
too the newer ones. So we don't know whether SFDP would be
accepted by other major SPI NOR manufactures like:
Spansion, Nymonix, Micronix, Toshiba, Samsung..

Thus, it might end-up like CFI (common flash interface) where some
vendors support it while others did not. So unless there are more
devices on SFDP from different vendors, I would prefer defer its
implementation in generic driver.

with regards, pekon


From pekon at ti.com  Fri Oct 11 05:30:48 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 11 Oct 2013 09:30:48 +0000
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <52566ACC.1080100@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk>	<52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>	<87hacq1d5k.fsf@dell.be.48ers.dk>
 <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>
 <52566ACC.1080100@ti.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA211D8@DBDE04.ent.ti.com>

Hi,

> From: Poddar, Sourav
> > On Thursday 10 October 2013 07:57 AM, Trent Piepho wrote:
> > I've found that the SPI layer adds rather a lot of overhead to SPI
> > transactions.  It appears to come mostly from using another thread to
> > run the queue.  A fast SPI message of a few dozen bytes ends up having
> > more overhead from the SPI layer than the time it takes the driver to
> > do the actual transfer.
> >
> > So memory mapped mode via some kind of SPI hack seems like a bad
> > design.  All the SPI layer overhead and you don't get DMA.  Memory
> > mapped SPI could be a win, but I think you'd need to do it at the MTD
> > layer with a mapping driver that could read the mmapped SPI flash
> > directly.
> Yes, you are correct in all your comments above. I also feel that SPI
> framework
> should be bypassed. But the subject patch is derived based on the
> following points/limitation:
> 
> 1. There is a setup register in QSPI, that need to be filled, as of now
> I am filling it
>      in my driver as a MACRO.
> 
Based on you previous information of set_up_register..
> > What is "set_up_register"?
> > set_up_register is a memory mapped specific register with the
> > following fields:
> > - RCMD (Read command, which is actually the flash read command)
> > - NUmber of Address bytes
> > - Number of dummy bytes
> > - Read type(Single, dual and quad read).
> > - Write command.

set_up_register should be filled from DT not from Macros, as these
value change from NAND device to device, and based on that
populate 'struct m25p' in m25p_probe().Otherwise it might end-up
in similar situation as in fsl_spinor driver.
Refer below as an example.
http://lists.infradead.org/pipermail/linux-mtd/2013-September/048552.html



> 2. Controller repsonds to memory mapped read for read opcodes,
>  so during the read path we should tell the controller to switch to
>  memory mapped port.
> 
As you would be know from DT when to enable MMODE, so you  can
actually make MM_MODE as your *default mode*. And only when
SPI framework is used you selectively switch to SPI_MODE and
revert back to MM_MODE while returning.

This way you can use memcpy() or dma_copy() directly in flash driver
like m25p80.c, and avoid getting SPI generic framework delays.
So, it should be like this..

/* Make MM_MODE your default mode in controller driver */
qspi_driver.c: configure_qspi_controller(mode) {
if (mode == MM_MODE)
	- do all your controller configurations for MM_MODE
	- do all OPCODE selections for MM_MODE
}

qspi_controller_probe()
	if (of_mode_property("spi-flash-memory-map") {
		spi->mode |= MM_MODE;
		/* configure_qspi_controller (MM_MODE) */
	} else {
		/* configure_qspi_controller(SPI_MODE) */
	}


/* Case 1: MM_MODE=enabled: Flash driver calls memcpy() */
m25p80.c: m25p80_quad_read() {
	if (flash->mmap_read)
		/* controller is already in MM_MODE by default */
		memcpy(*from, *to, length);
	else
		/* usual call to spi_framework */
}


/* Case 2: SPI_MODE=enabled: Flash driver follows spi framework */
m25p80.c: m25p80_quad_read() {
	if (flash->mmap_read)
		/* ignored */
	else
		spi_add_message_to_tail();
}	

qspi_driver.c: prepare_transfer_hardware()
	if (spi->mode & MM_MODE) {
		/* controller is in MM_MODE by default, so switch
		  * to controller to SPI_MODE */
		configure_qspi_controller (SPI_MODE);
	} else {
		/* controller is already in SPI_MODE always */
	}

qspi_driver.c: transfer_one_message ()
	if (spi->mode & MM_MODE) {
		/* controller was switched to SPI_MODE in
		* prepare_transfer_hardware(),so revert back
		  * back to MM_MODE */
		configure_qspi_controller (MM_MODE);
	} else {
		/* controller is already in SPI_MODE always*/
	}
}

*Important*
But you need to be careful, because  you need to synchronize
with kthread_worker running inside SPI generic framework.
So, lock your spi_controller while doing MMODE accesses.
else you might end up in situation where a starving kthead_worker
suddenly woke-up  and changed your configurations from MMODE to
SPI_MODE in between ongoing memcpy() or dma_cpy().

(Request David W, and Mark B to please review this proposal
 based on m25p80.c and SPI generic framework, as I may be
 missing some understanding here).


with regards, pekon


From broonie at kernel.org  Fri Oct 11 05:59:48 2013
From: broonie at kernel.org (Mark Brown)
Date: Fri, 11 Oct 2013 10:59:48 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXigijA6ASOiHkRDz45PTruv2vwYJu0UUWz0hvKr0=zwu5w@mail.gmail.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-2-git-send-email-sourav.poddar@ti.com>
 <20131009160759.GQ21581@sirena.org.uk> <52558A49.5090904@ti.com>
 <20131009174027.GS21581@sirena.org.uk>
 <87hacq1d5k.fsf@dell.be.48ers.dk>
 <CA+7tXii4J_Hie2v-DaSevFHn-YqriiVowhpXCP9H+U51_tbhvQ@mail.gmail.com>
 <20131010101052.GF21581@sirena.org.uk>
 <CA+7tXigijA6ASOiHkRDz45PTruv2vwYJu0UUWz0hvKr0=zwu5w@mail.gmail.com>
Message-ID: <20131011095948.GZ21581@sirena.org.uk>

On Thu, Oct 10, 2013 at 04:53:46PM -0700, Trent Piepho wrote:
> On Thu, Oct 10, 2013 at 3:10 AM, Mark Brown <broonie at kernel.org> wrote:

> > Yeah, though of course at the minute the implementation of that thread
> > is pretty much up to the individual drivers which isn't triumph - and
> > the quality of implementation does vary rather a lot. I'm currently
> > working on trying to factor more of this out, hopefully then it'll be
> > easier to push out improvements. It may be nice to be able to kick off
> > the first DMA transfer from within the caller for example.

> I did testing with the mxs driver, which uses transfer_one
> _message and the spi core queue pumping code.  For small messages the
> overhead of queuing work to the pump_messages queue and waiting for
> completion is rather more than the time the actual transfer takes.  Which
> makes using a kthread rather pointless.  Part of the problem could be the
> high context switch cost for ARMv5.

Indeed - that's what I'd expect to happen.  Sufficiently small PIO
transfers and DMA initiation should both be faster if done from the
calling context.  The thread starts to get more useful once you start
building up work (at which point it should reduce context switches,
especially if multiple threads are using the bus) and if the system is
very heavily loaded when you can raise the thread priority so it can
drive data in more quickly.  

That said it's also helpful in terms of making the code simpler to just
have the one data path.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/871f0e3c/attachment.sig>

From broonie at kernel.org  Fri Oct 11 06:08:39 2013
From: broonie at kernel.org (Mark Brown)
Date: Fri, 11 Oct 2013 11:08:39 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <52568AA3.9080203@ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com>
Message-ID: <20131011100839.GA21581@sirena.org.uk>

On Thu, Oct 10, 2013 at 04:38:19PM +0530, Sourav Poddar wrote:
> On Thursday 10 October 2013 03:44 PM, Mark Brown wrote:

> >Essentially what it looks like this hardware is trying to do is adapt a
> >serial flash so it looks more like a parallel flash.  It's not clear
> >that this is a good idea if we are already able to understand serial
> >flash though.

> Do you have any idea of how to go about implementing it in a more
> cleaner way?(taking care of all what the spi controller hardware needs to
> do for the memory mapped mode.). I understand doing a memcpy in the caller
> itself, but how to tackle the spi controller configuration at that
> point of time.

You'd need to lock the bus and return the address for the caller to use
until it released the lock.  Like I say I'd want to see numbers on this
helping though.

> Memory mapped is  a spi controller feature rather than a flash.

The way it appears to be implemented is pretty flash specific isn't it?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/8520c573/attachment.sig>

From pekon at ti.com  Fri Oct 11 06:17:48 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 11 Oct 2013 10:17:48 +0000
Subject: [PATCH v7 1/6] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA1F3DC@DBDE04.ent.ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-2-git-send-email-pekon@ti.com>
 <20131007112728.GA15365@e106331-lin.cambridge.arm.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA1F3DC@DBDE04.ent.ti.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2122E@DBDE04.ent.ti.com>

Dear MTD Maintainers,

> >
> > If I have my NAND formatted with one of the existing ECC schemes (e.g.
> > OMAP_ECC_HAMMING_CODE_DEFAULT) will it work with the new
> > OMAP_ECC_HAM1_CODE_HW scheme?
> >
> > Are they all compatible?
> >
> Yes, they all are 1-bit hamming code, the only difference between
> xx_Default and xx_HW was who was doing the ECC calculation.
> For xx_DEFAULT: ECC calculation was done on CPU via s/w library
> For xx_HW: ECC calculation was done by in-build h/w engine.
> So, all HAMMING_xx can be replaced by HAM1_HW.
> 
> [snip]
> 
> > > @@ -1342,9 +1342,7 @@ static void __maybe_unused
> > gpmc_read_timings_dt(struct device_node *np,
> > >  #ifdef CONFIG_MTD_NAND
> > >
> > >  static const char * const nand_ecc_opts[] = {
> > > -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> > > -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> > > -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-
> > romcode",
> > > +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> > >  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> > >  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> >
> > Won't this break existing dts which have "sw", "hw", or "hw-romcode"?
> >
> > Someone may try to use a new kernel with an old dt, and we marked them
> > as deprecated, not removed.
> >
> HAMMING_xx ECC scheme was used only on legacy platforms, when
> BCH8 was not available, I have not seen anyone using this scheme
> *from mainline kernel* from quite a long time. So, it's safe to remove them.
> 
> This is what was concluded as per below email.
> http://lists.infradead.org/pipermail/linux-mtd/2013-September/048876.html
> 

This patch-series and its follow-on series has already missed many merge
windows, And the above discussion has reached a stalled state (infinite loop)
where, I cannot revert some DT binding updates to and fro to keep all legacy
DT bindings backward compatible forever.
However, I can assure that these DT updates make binding stable for long-term.

So now it's your discretion to whether to accept or leave following 2 series:

http://lists.infradead.org/pipermail/linux-mtd/2013-October/048983.html

http://lists.infradead.org/pipermail/linux-mtd/2013-October/049008.html


AFAIK no-one is using Hamming based ecc-scheme on OMAP platforms
*from mainline kernel*. So this DT update actually does not affect users
I know of. Rather these patch series was intended for long term scalability
and clean-up so that more OMAP users migrate to mainline kernel easily.


with regards, pekon 


From balbi at ti.com  Fri Oct 11 07:53:27 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 06:53:27 -0500
Subject: [PATCH v7 1/6] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2122E@DBDE04.ent.ti.com>
References: <1380916188-24206-1-git-send-email-pekon@ti.com>
 <1380916188-24206-2-git-send-email-pekon@ti.com>
 <20131007112728.GA15365@e106331-lin.cambridge.arm.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA1F3DC@DBDE04.ent.ti.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2122E@DBDE04.ent.ti.com>
Message-ID: <20131011115327.GA25706@radagast>

Hi Pekon,

On Fri, Oct 11, 2013 at 05:17:48AM -0500, Gupta, Pekon wrote:
> > > If I have my NAND formatted with one of the existing ECC schemes (e.g.
> > > OMAP_ECC_HAMMING_CODE_DEFAULT) will it work with the new
> > > OMAP_ECC_HAM1_CODE_HW scheme?
> > >
> > > Are they all compatible?
> > >
> > Yes, they all are 1-bit hamming code, the only difference between
> > xx_Default and xx_HW was who was doing the ECC calculation.
> > For xx_DEFAULT: ECC calculation was done on CPU via s/w library
> > For xx_HW: ECC calculation was done by in-build h/w engine.
> > So, all HAMMING_xx can be replaced by HAM1_HW.
> > 
> > [snip]
> > 
> > > > @@ -1342,9 +1342,7 @@ static void __maybe_unused
> > > gpmc_read_timings_dt(struct device_node *np,
> > > >  #ifdef CONFIG_MTD_NAND
> > > >
> > > >  static const char * const nand_ecc_opts[] = {
> > > > -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> > > > -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> > > > -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-
> > > romcode",
> > > > +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> > > >  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> > > >  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> > >
> > > Won't this break existing dts which have "sw", "hw", or "hw-romcode"?
> > >
> > > Someone may try to use a new kernel with an old dt, and we marked them
> > > as deprecated, not removed.
> > >
> > HAMMING_xx ECC scheme was used only on legacy platforms, when
> > BCH8 was not available, I have not seen anyone using this scheme
> > *from mainline kernel* from quite a long time. So, it's safe to remove them.
> > 
> > This is what was concluded as per below email.
> > http://lists.infradead.org/pipermail/linux-mtd/2013-September/048876.html
> > 
> 
> This patch-series and its follow-on series has already missed many merge
> windows, And the above discussion has reached a stalled state (infinite loop)
> where, I cannot revert some DT binding updates to and fro to keep all legacy
> DT bindings backward compatible forever.
> However, I can assure that these DT updates make binding stable for long-term.
> 
> So now it's your discretion to whether to accept or leave following 2 series:
> 
> http://lists.infradead.org/pipermail/linux-mtd/2013-October/048983.html
> 
> http://lists.infradead.org/pipermail/linux-mtd/2013-October/049008.html
> 
> 
> AFAIK no-one is using Hamming based ecc-scheme on OMAP platforms
> *from mainline kernel*. So this DT update actually does not affect users
> I know of. Rather these patch series was intended for long term scalability
> and clean-up so that more OMAP users migrate to mainline kernel easily.

wouldn't something like below maintain backwards compatibility ?

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 579697a..f33ffe0 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1383,6 +1383,10 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 			if (!strcasecmp(s, nand_ecc_opts[val])) {
 				gpmc_nand_data->ecc_opt = val;
 				break;
+			} else if (!strcasecmp(s, "sw") ||
+					!strcasecmp(s, "hw") ||
+					!strcasecmp(s, "hw-romcode")) {
+				gpmc_nand_data->ecc_opt = OMAP_ECC_HAM1_CODE_HW;
 			}
 
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/2091c13b/attachment-0001.sig>

From pekon at ti.com  Fri Oct 11 09:36:37 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:37 +0530
Subject: [PATCH v8 0/6] mtd:nand:omap2: clean-up of supported ECC schemes
Message-ID: <1381498603-15715-1-git-send-email-pekon@ti.com>

*Changes v7 -> v8*
[PATCH 1/6] <no updates>
[PATCH 2/6]
	- updated DT parsing of "ti,nand-ecc-opts" so that its "ham1" remains
		compatible to "sw","hw","hw-romcode"
	- updated DT parsing of "ti,elm-id" to retain compatibility to "elm_id"
	- using of_parse_phandle() to get ELM device pointer from DT
[PATCH 3..6/6] <commit log updates>


*Changes v6 -> v7*
[PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks of Brain Norris
[PATCH 2/6] incorporated feedbacks from DT maintainers
[PATCH 3/6] patch cleaning and incorporated feedbacks from Brain Norris
[PATCH 4/6] rebasing changes and cleanup
[PATCH 5/6] updated omap3430-sdp.dts
[PATCH 6/6] <NEW> updated for devm_xx


*Changes v5 -> v6*
[PATCH 1/4]: 
	- updated DT binding for gpmc-nand based on 'Olof Johansson's feedbacks
	http://lists.infradead.org/pipermail/linux-mtd/2013-August/048394.html
	- detection of ELM device via ti,elm-id DT node, moved to gpmc.c driver
[PATCH 2/4]
	- removed: support for following obselete ECC schemes
	OMAP_ECC_HAMMING_CODE_DEFAULT (S/W based 1-bit Hamming ECC)
	OMAP_ECC_HAMMING_CODE_HW_ROMCODE (H/W based 1-bit Hamming ECC scheme)
	- updated: using omap_oobinfo as chip->ecc.layout for all ecc-schemes
	- clean: error messages
[PATCH 3/4] cleaned to include changes for OMAP_ECC_BCH8_CODE_HW only
[PATCH 4/4] updated to include DT property changes


*Changes v4 -> v5*
- Rebased to linux-next 
IMPORTANT: Need to revert commit fb1585b, [PATCH 2/4] part of previous version
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047441.html

- Swapped PATCH-1 & PATCH-2 to maintain bisectibility & compilation dependency
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047461.html

- PATCH-2: re-ordered call to is_elm_present() for later updates ELM driver
	- dropped changes in include/linux/platform_data/elm.h (not needed)
- PATCH-3: re-ordered call to is_elm_present() for later updates ELM driver
- Re-formated patch description (replaced tabs with white-spaces)


*Changes v3 -> v4*
(Resent with CC: devicetree-discuss at lists.ozlabs.org)
- [Patch 1/3] removed MTD_NAND_OMAP_BCH8 & MTD_NAND_OMAP_BCH4 from nand/Kconfig
	ECC scheme selectable via nand DT (nand-ecc-opt).
- [*] rebased for l2-mtd.git


*Changes v2 -> v3*
(Resent with Author Name fixed)
- PATCH-1: re-arranged code to remove redundancy, added NAND_BUSWIDTH_AUTO
- PATCH-2: updated nand-ecc-opt DT mapping and Documentation
- PATCH-3: code-cleaning + changes to match PATCH-1
- PATCH-4 <DROPPED> update DT attribute for ti,nand-ecc-opt 
	- received feedback to keep DT mapping independent of linuxism
- PATCH-4:<NEW> : ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
	- independent patch for AM335x-evm.dts update based on PATCH-2


*Changes v1 -> v2*
	added 	[PATCH 3/4] and [PATCH 4/4]


After this patch series, omap2-nand driver will supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+

To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine


Pekon Gupta (6):
  mtd: nand: omap: combine different flavours of 1-bit hamming ecc
    schemes
  ARM: OMAP2+: cleaned-up DT support of various ECC schemes
  mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
    device_probe
  mtd:nand:omap2: updated support for BCH4 ECC scheme
  ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
  mtd: nand: omap: updated devm_xx for all resource allocation and free
    calls

 .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
 arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
 arch/arm/mach-omap2/board-flash.c                  |   2 +-
 arch/arm/mach-omap2/gpmc.c                         |  47 +-
 drivers/mtd/nand/Kconfig                           |  30 +-
 drivers/mtd/nand/omap2.c                           | 569 ++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
 8 files changed, 333 insertions(+), 354 deletions(-)

-- 
1.8.1



From pekon at ti.com  Fri Oct 11 09:36:38 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:38 +0530
Subject: [PATCH v8 1/6] mtd: nand: omap: combine different flavours of 1-bit
 hamming ecc schemes
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <1381498603-15715-2-git-send-email-pekon@ti.com>

OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
ecc-scheme, like:
- OMAP_ECC_HAMMING_CODE_DEFAULT
	1-bit hamming ecc code using software library
- OMAP_ECC_HAMMING_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine
- OMAP_ECC_HAMMING_CODE_HW_ROMCODE
	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
	to ROM code.

This patch combines above multiple ecc-schemes into single implementation:
- OMAP_ECC_HAM1_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
	ecc-layout.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
 arch/arm/mach-omap2/board-flash.c                   | 2 +-
 arch/arm/mach-omap2/gpmc.c                          | 4 +---
 drivers/mtd/nand/omap2.c                            | 9 +++------
 include/linux/platform_data/mtd-nand-omap2.h        | 6 +-----
 5 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index df338cb..25ee232 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -22,10 +22,10 @@ Optional properties:
 				width of 8 is assumed.
 
  - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-
-		"sw"		Software method (default)
-		"hw"		Hardware method
-		"hw-romcode"	gpmc hamming mode method & romcode layout
+		"sw"		<deprecated> use "ham1" instead
+		"hw"		<deprecated> use "ham1" instead
+		"hw-romcode"	<deprecated> use "ham1" instead
+		"ham1"		1-bit Hamming ecc code
 		"bch4"		4-bit BCH ecc code
 		"bch8"		8-bit BCH ecc code
 
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index fc20a61..ac82512 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
 
-	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
 	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/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 579697a..c9fb353 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1342,9 +1342,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 #ifdef CONFIG_MTD_NAND
 
 static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
-	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
-	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
+	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
 	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
 	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
 };
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..8d521aa 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1993,10 +1993,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
-		info->nand.ecc.mode = NAND_ECC_SOFT;
-	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
-		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 		info->nand.ecc.bytes            = 3;
 		info->nand.ecc.size             = 512;
 		info->nand.ecc.strength         = 1;
@@ -2025,7 +2022,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
 		if (info->nand.options & NAND_BUSWIDTH_16)
 			offset = 2;
@@ -2033,7 +2030,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			offset = 1;
 			info->nand.badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16);
+		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 6bf9ef4..cb5a54a 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,11 +23,7 @@ enum nand_io {
 };
 
 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_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
 	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
 	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
 };
-- 
1.8.1



From pekon at ti.com  Fri Oct 11 09:36:39 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:39 +0530
Subject: [PATCH v8 2/6] ARM: OMAP2+: cleaned-up DT support of various ECC
 schemes
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <1381498603-15715-3-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in following
different flavours, depending on in-build Hardware engines supported by SoC.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+
To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine

DT binding updates in this patch are:
- ti,elm-id: replaces elm_id
- ti,nand-ecc-opts: supported values ham1, bch4, and bch8
	selection of h/w or s/w implementation depends on ti,elm-id

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
 arch/arm/mach-omap2/gpmc.c                         | 45 ++++++++++++++++------
 include/linux/platform_data/mtd-nand-omap2.h       | 14 +++++--
 3 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 25ee232..5e1f31b 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -36,8 +36,12 @@ Optional properties:
 		"prefetch-dma"		Prefetch enabled sDMA mode
 		"prefetch-irq"		Prefetch enabled irq mode
 
- - elm_id:	Specifies elm device node. This is required to support BCH
- 		error correction using ELM module.
+ - elm_id:	<deprecated> use "ti,elm-id" instead
+ - ti,elm-id:	Specifies phandle of the ELM devicetree node.
+		ELM is an on-chip hardware engine on TI SoC which is used for
+		locating ECC errors for BCHx algorithms. SoC devices which have
+		ELM hardware engines should specify this device node in .dtsi
+		Using ELM for ECC error correction frees some CPU cycles.
 
 For inline partiton table parsing (optional):
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c9fb353..9473c9f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1341,12 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 
 #ifdef CONFIG_MTD_NAND
 
-static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
-	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
-	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
-};
-
 static const char * const nand_xfer_types[] = {
 	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
 	[NAND_OMAP_POLLED]			= "polled",
@@ -1376,12 +1370,39 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 	gpmc_nand_data->cs = val;
 	gpmc_nand_data->of_node = child;
 
-	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-			if (!strcasecmp(s, nand_ecc_opts[val])) {
-				gpmc_nand_data->ecc_opt = val;
-				break;
-			}
+	/* Detect availability of ELM module */
+	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		gpmc_nand_data->elm_of_node =
+					of_parse_phandle(child, "elm_id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		pr_warn("%s: ti,elm-id property not found\n", __func__);
+
+	/* select NAND ecc-opt */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!strcmp(s, "ham1") || !strcmp(s, "sw") ||
+		!strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
+		gpmc_nand_data->ecc_opt =
+				OMAP_ECC_HAM1_CODE_HW;
+	else if (!strcmp(s, "bch4"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	else if (!strcmp(s, "bch8"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	else
+		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
 
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
 		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index cb5a54a..4da5bfa 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,9 +23,16 @@ enum nand_io {
 };
 
 enum omap_ecc {
-	OMAP_ECC_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
-	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
-	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
+	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_HAM1_CODE_HW = 0,
+	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH4_CODE_HW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH8_CODE_HW,
 };
 
 struct gpmc_nand_regs {
@@ -59,5 +66,6 @@ struct omap_nand_platform_data {
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
+	struct device_node	*elm_of_node;
 };
 #endif
-- 
1.8.1



From pekon at ti.com  Fri Oct 11 09:36:40 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:40 +0530
Subject: [PATCH v8 3/6] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <1381498603-15715-4-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in following
different flavours, depending on in-build Hardware engines supported by SoC.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+
To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        enables S/W based BCH ECC algorithm
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       enables H/W based BCH ECC algorithm

This patch
- separates the configurations code for each ECC schemes
- fixes dependency issues based on Kconfig options
- updates ELM device detection in is_elm_present()
- cleans redundant code

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 450 +++++++++++++++++++++++------------------------
 1 file changed, 220 insertions(+), 230 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8d521aa..fb96251 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,8 +25,10 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 #include <linux/bch.h>
+#endif
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/platform_data/elm.h>
 #endif
 
@@ -141,6 +143,9 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define BADBLOCK_MARKER_LENGTH		2
+#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
+
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 	0xac, 0x6b, 0xff, 0x99, 0x7b};
@@ -182,14 +187,11 @@ struct omap_nand_info {
 	u_char				*buf;
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-	struct bch_control             *bch;
-	struct nand_ecclayout           ecclayout;
+	/* fields specific for BCHx_HW ECC scheme */
+	struct bch_control              *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
-#endif
 };
 
 /**
@@ -1058,8 +1060,7 @@ static int omap_dev_ready(struct mtd_info *mtd)
 	}
 }
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
  * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
  * @mtd: MTD device structure
@@ -1140,7 +1141,9 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	/* Clear ecc and enable bits */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
+#endif
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
  * @mtd: MTD device structure
@@ -1225,7 +1228,9 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 
 	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1517,7 +1522,9 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
+#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_correct_data_bch - Decode received data and correct errors
  * @mtd: MTD device structure
@@ -1549,7 +1556,9 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
 	}
 	return count;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1637,197 +1646,68 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
+ * is_elm_present - checks for presence of ELM module by scanning DT nodes
+ * @omap_nand_info: NAND device structure containing platform data
+ * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16
  */
-static void omap3_free_bch(struct mtd_info *mtd)
+static int is_elm_present(struct omap_nand_info *info,
+			struct device_node *elm_node, enum bch_ecc bch_type)
 {
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-/**
- * omap3_init_bch - Initialize BCH ECC
- * @mtd: MTD device structure
- * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW)
- */
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	int max_errors;
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-#ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = BCH8_MAX_ERROR;
-#else
-	const int hw_errors = BCH4_MAX_ERROR;
-#endif
-	enum bch_ecc bch_type;
-	const __be32 *parp;
-	int lenp;
-	struct device_node *elm_node;
-
-	info->bch = NULL;
-
-	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);
-		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 = max_errors;
-
-	if (hw_errors == BCH8_MAX_ERROR)
-		bch_type = BCH8_ECC;
-	else
-		bch_type = BCH4_ECC;
-
-	/* Detect availability of ELM module */
-	parp = of_get_property(info->of_node, "elm_id", &lenp);
-	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
-		pr_err("Missing elm_id property, fall back to Software BCH\n");
-		info->is_elm_used = false;
-	} else {
-		struct platform_device *pdev;
-
-		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
-		pdev = of_find_device_by_node(elm_node);
-		info->elm_dev = &pdev->dev;
-
-		if (elm_config(info->elm_dev, bch_type) == 0)
-			info->is_elm_used = true;
+	struct platform_device *pdev;
+	info->is_elm_used = false;
+	/* check whether elm-id is passed via DT */
+	if (!elm_node) {
+		pr_err("nand: error: ELM DT node not found\n");
+		return -ENODEV;
 	}
-
-	if (info->is_elm_used && (mtd->writesize <= 4096)) {
-
-		if (hw_errors == BCH8_MAX_ERROR)
-			info->nand.ecc.bytes = BCH8_SIZE;
-		else
-			info->nand.ecc.bytes = BCH4_SIZE;
-
-		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;
-	} else {
-		/*
-		 * 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;
-		}
+	pdev = of_find_device_by_node(elm_node);
+	/* check whether ELM device is registered */
+	if (!pdev) {
+		pr_err("nand: error: ELM device not found\n");
+		return -ENODEV;
 	}
-
-	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
+	/* ELM module available, now configure it */
+	info->elm_dev = &pdev->dev;
+	if (elm_config(info->elm_dev, bch_type))
+		return -ENODEV;
+	info->is_elm_used = true;
 	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
- * omap3_init_bch_tail - Build an oob layout for BCH ECC correction.
+ * omap3_free_bch - Release BCH ecc resources
  * @mtd: MTD device structure
  */
-static int omap3_init_bch_tail(struct mtd_info *mtd)
+static void omap3_free_bch(struct mtd_info *mtd)
 {
-	int i, steps, offset;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-	struct nand_ecclayout *layout = &info->ecclayout;
-
-	/* build oob layout */
-	steps = mtd->writesize/info->nand.ecc.size;
-	layout->eccbytes = steps*info->nand.ecc.bytes;
-
-	/* do not bother creating special oob layouts for small page devices */
-	if (mtd->oobsize < 64) {
-		pr_err("BCH ecc is not supported on small page devices\n");
-		goto fail;
-	}
-
-	/* reserve 2 bytes for bad block marker */
-	if (layout->eccbytes+2 > mtd->oobsize) {
-		pr_err("no oob layout available for oobsize %d eccbytes %u\n",
-		       mtd->oobsize, layout->eccbytes);
-		goto fail;
+	if (info->bch) {
+		free_bch(info->bch);
+		info->bch = NULL;
 	}
-
-	/* 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] = 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].length = mtd->oobsize-2-layout->eccbytes;
-	info->nand.ecc.layout = layout;
-
-	if (!(info->nand.options & NAND_BUSWIDTH_16))
-		info->nand.badblock_pattern = &bb_descrip_flashbased;
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
 
 #else
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n");
-	return -1;
-}
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	return -1;
-}
+
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
 	struct omap_nand_platform_data	*pdata;
+	struct mtd_info			*mtd;
+	struct nand_chip		*nand_chip;
+	struct nand_ecclayout		*ecclayout;
 	int				err;
-	int				i, offset;
-	dma_cap_mask_t mask;
-	unsigned sig;
+	int				i;
+	dma_cap_mask_t			mask;
+	unsigned			sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
 
@@ -1846,20 +1726,18 @@ static int omap_nand_probe(struct platform_device *pdev)
 	spin_lock_init(&info->controller.lock);
 	init_waitqueue_head(&info->controller.wq);
 
-	info->pdev = pdev;
-
+	mtd			= &info->mtd;
+	mtd->name		= dev_name(&pdev->dev);
+	mtd->owner		= THIS_MODULE;
+	mtd->priv		= &info->nand;
+	nand_chip		= &info->nand;
+	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
+	info->bch		= NULL;
 
-	info->mtd.priv		= &info->nand;
-	info->mtd.name		= dev_name(&pdev->dev);
-	info->mtd.owner		= THIS_MODULE;
-
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 	info->of_node		= pdata->of_node;
-#endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
@@ -1903,6 +1781,30 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->nand.chip_delay = 50;
 	}
 
+	/* scan NAND device conncted to controller */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		err = -ENXIO;
+		goto out_release_mem_region;
+	}
+	pr_info("%s: detected %s NAND flash\n", DRIVER_NAME,
+			(nand_chip->options & NAND_BUSWIDTH_16) ? "x16" : "x8");
+	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
+			(pdata->devsize & NAND_BUSWIDTH_16)) {
+		pr_err("%s: but incorrectly configured as %s", DRIVER_NAME,
+			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* check for small page devices */
+	if ((mtd->oobsize < 64) &&
+		(pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
+		pr_err("small page devices are not supported\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* populate read & write API based on xfer_type selected */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		info->nand.read_buf   = omap_read_buf_pref;
@@ -1992,61 +1894,148 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-		info->nand.ecc.bytes            = 3;
-		info->nand.ecc.size             = 512;
-		info->nand.ecc.strength         = 1;
-		info->nand.ecc.calculate        = omap_calculate_ecc;
-		info->nand.ecc.hwctl            = omap_enable_hwecc;
-		info->nand.ecc.correct          = omap_correct_data;
-		info->nand.ecc.mode             = NAND_ECC_HW;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(&info->mtd, pdata->ecc_opt);
-		if (err) {
+	/* populate MTD interface based on ECC scheme */
+	nand_chip->ecc.layout	= &omap_oobinfo;
+	ecclayout		= &omap_oobinfo;
+	switch (pdata->ecc_opt) {
+	case OMAP_ECC_HAM1_CODE_HW:
+		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
+		nand_chip->ecc.mode             = NAND_ECC_HW;
+		nand_chip->ecc.bytes            = 3;
+		nand_chip->ecc.size             = 512;
+		nand_chip->ecc.strength         = 1;
+		nand_chip->ecc.calculate        = omap_calculate_ecc;
+		nand_chip->ecc.hwctl            = omap_enable_hwecc;
+		nand_chip->ecc.correct          = omap_correct_data;
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		if (nand_chip->options & NAND_BUSWIDTH_16)
+			ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
+		else
+			ecclayout->eccpos[0]	= 1;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		break;
+
+	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 7;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
-			goto out_release_mem_region;
 		}
-	}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
-			err = -ENXIO;
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 13;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
+			err = -EINVAL;
 			goto out_release_mem_region;
 		}
-	}
-
-	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
 
-		if (info->nand.options & NAND_BUSWIDTH_16)
-			offset = 2;
-		else {
-			offset = 1;
-			info->nand.badblock_pattern = &bb_descrip_flashbased;
-		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
-		for (i = 0; i < omap_oobinfo.eccbytes; i++)
-			omap_oobinfo.eccpos[i] = i+offset;
-
-		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = info->mtd.oobsize -
-					(offset + omap_oobinfo.eccbytes);
-
-		info->nand.ecc.layout = &omap_oobinfo;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(&info->mtd);
-		if (err) {
-			err = -EINVAL;
+	case OMAP_ECC_BCH8_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 13 + 1;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
 			goto out_release_mem_region;
 		}
+		/* define custom ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	default:
+		pr_err("nand: error: invalid or unsupported ECC scheme\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* populate remaining info for custom ecc layout */
+	pr_info("%s: using custom ecc layout\n", DRIVER_NAME);
+	ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH
+						- ecclayout->eccbytes;
+	if (!(nand_chip->options & NAND_BUSWIDTH_16))
+		nand_chip->badblock_pattern = &bb_descrip_flashbased;
+	for (i = 1; i < ecclayout->eccbytes; i++)
+		ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
+	/* check if NAND OOBSIZE meets ECC scheme requirement */
+	if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
+		pr_err("not enough OOB bytes required = %d, available=%d\n",
+			ecclayout->eccbytes, mtd->oobsize);
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* second phase scan */
@@ -2072,6 +2061,7 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
+	omap3_free_bch(&info->mtd);
 	kfree(info);
 
 	return err;
-- 
1.8.1



From pekon at ti.com  Fri Oct 11 09:36:41 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:41 +0530
Subject: [PATCH v8 4/6] mtd:nand:omap2: updated support for BCH4 ECC scheme
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <1381498603-15715-5-git-send-email-pekon@ti.com>

This patch adds following two flavours of BCH4 ECC scheme in omap2-nand driver
- OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
	- uses GPMC H/W engine for calculating ECC.
	- uses software library (lib/bch.h & nand_bch.h) for error correction.

- OMAP_ECC_BCH4_CODE_HW
	- uses GPMC H/W engine for calculating ECC.
	- uses ELM H/W engine for error correction.

With this patch omap2-nand driver supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
+---------------------------------------+---------------+---------------+
Important:
- Selection of OMAP_ECC_BCHx_CODE_HW_DETECTION_SW requires,
	Kconfig: CONFIG_MTD_NAND_ECC_BCH: enables S/W based BCH ECC algorithm.

- Selection of OMAP_ECC_BCHx_CODE_HW requires,
	Kconfig: CONFIG_MTD_NAND_OMAP_BCH: enables ELM H/W module.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/Kconfig |  30 ++---------
 drivers/mtd/nand/omap2.c | 134 +++++++++++++++++++++--------------------------
 2 files changed, 63 insertions(+), 101 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..5836039 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
 
 config MTD_NAND_OMAP_BCH
 	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
-	tristate "Enable support for hardware BCH error correction"
+	tristate "Support hardware based BCH error correction"
 	default n
 	select BCH
-	select BCH_CONST_PARAMS
 	help
-	 Support for hardware BCH error correction.
-
-choice
-	prompt "BCH error correction capability"
-	depends on MTD_NAND_OMAP_BCH
-
-config MTD_NAND_OMAP_BCH8
-	bool "8 bits / 512 bytes (recommended)"
-	help
-	 Support correcting up to 8 bitflips per 512-byte block.
-	 This will use 13 bytes of spare area per 512 bytes of page data.
-	 This is the recommended mode, as 4-bit mode does not work
-	 on some OMAP3 revisions, due to a hardware bug.
-
-config MTD_NAND_OMAP_BCH4
-	bool "4 bits / 512 bytes"
-	help
-	 Support correcting up to 4 bitflips per 512-byte block.
-	 This will use 7 bytes of spare area per 512 bytes of page data.
-	 Note that this mode does not work on some OMAP3 revisions, due to a
-	 hardware bug. Please check your OMAP datasheet before selecting this
-	 mode.
-
-endchoice
+	  Some devices have built-in ELM hardware engine, which can be used to
+	  locate and correct errors when using BCH ECC scheme. This enables the
+	  driver support for same.
 
 if MTD_NAND_OMAP_BCH
 config BCH_CONST_M
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index fb96251..a783dae 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -27,6 +27,7 @@
 
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 #include <linux/bch.h>
+#include <linux/mtd/nand_bch.h>
 #endif
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/platform_data/elm.h>
@@ -144,7 +145,6 @@
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
 #define BADBLOCK_MARKER_LENGTH		2
-#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
@@ -188,7 +188,6 @@ struct omap_nand_info {
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
-	struct bch_control              *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1522,43 +1521,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_correct_data_bch - Decode received data and correct errors
- * @mtd: MTD device structure
- * @data: page data
- * @read_ecc: ecc read from nand flash
- * @calc_ecc: ecc read from HW ECC registers
- */
-static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
-				  u_char *read_ecc, u_char *calc_ecc)
-{
-	int i, count;
-	/* cannot correct more than 8 errors */
-	unsigned int errloc[8];
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-
-	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
-			   errloc);
-	if (count > 0) {
-		/* correct errors */
-		for (i = 0; i < count; i++) {
-			/* correct data only, not ecc bytes */
-			if (errloc[i] < 8*512)
-				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
-			pr_debug("corrected bitflip %u\n", errloc[i]);
-		}
-	} else if (count < 0) {
-		pr_err("ecc unrecoverable error\n");
-	}
-	return count;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1675,28 +1638,6 @@ static int is_elm_present(struct omap_nand_info *info,
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
- */
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-#else
-
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
@@ -1731,10 +1672,10 @@ static int omap_nand_probe(struct platform_device *pdev)
 	mtd->owner		= THIS_MODULE;
 	mtd->priv		= &info->nand;
 	nand_chip		= &info->nand;
+	nand_chip->ecc.priv	= NULL;
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-	info->bch		= NULL;
 
 	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 	info->of_node		= pdata->of_node;
@@ -1927,7 +1868,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		info->nand.ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1937,10 +1878,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		info->nand.ecc.priv		= nand_bch_init(mtd,
+							info->nand.ecc.size,
+							info->nand.ecc.bytes,
+							&info->nand.ecc.layout);
+		if (!info->nand.ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 		}
@@ -1951,6 +1893,39 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 #endif
 
+	case OMAP_ECC_BCH4_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
+		info->nand.ecc.mode		= NAND_ECC_HW;
+		info->nand.ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		info->nand.ecc.bytes		= 7 + 1;
+		info->nand.ecc.strength		= 4;
+		info->nand.ecc.hwctl		= omap3_enable_hwecc_bch;
+		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;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			err = -ENODEV;
+			goto out_release_mem_region;
+		}
+		/* define ECC layout */
+		ecclayout->eccbytes		= info->nand.ecc.bytes *
+							(mtd->writesize /
+							info->nand.ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
@@ -1959,7 +1934,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		info->nand.ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
 		/* define custom ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1969,10 +1944,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		info->nand.ecc.priv		= nand_bch_init(mtd,
+							info->nand.ecc.size,
+							info->nand.ecc.bytes,
+							&info->nand.ecc.layout);
+		if (!info->nand.ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2023,7 +1999,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* populate remaining info for custom ecc layout */
-	pr_info("%s: using custom ecc layout\n", DRIVER_NAME);
 	ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH
 						- ecclayout->eccbytes;
 	if (!(nand_chip->options & NAND_BUSWIDTH_16))
@@ -2061,7 +2036,12 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
-	omap3_free_bch(&info->mtd);
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+	if (info->nand.ecc.priv) {
+		nand_bch_free(info->nand.ecc.priv);
+		info->nand.ecc.priv = NULL;
+	}
+#endif
 	kfree(info);
 
 	return err;
@@ -2072,8 +2052,12 @@ static int omap_nand_remove(struct platform_device *pdev)
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(&info->mtd);
-
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+	if (info->nand.ecc.priv) {
+		nand_bch_free(info->nand.ecc.priv);
+		info->nand.ecc.priv = NULL;
+	}
+#endif
 	if (info->dma)
 		dma_release_channel(info->dma);
 
-- 
1.8.1



From pekon at ti.com  Fri Oct 11 09:36:42 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:42 +0530
Subject: [PATCH v8 5/6] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <1381498603-15715-6-git-send-email-pekon@ti.com>

Updated DTS to replace deprecated binding with newer values
Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 arch/arm/boot/dts/am335x-evm.dts   | 3 +--
 arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e8ec875..1aee6ac 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -269,7 +269,6 @@
 				reg = <0 0 0>; /* CS0, offset 0 */
 				nand-bus-width = <8>;
 				ti,nand-ecc-opt = "bch8";
-				gpmc,device-nand = "true";
 				gpmc,device-width = <1>;
 				gpmc,sync-clk-ps = <0>;
 				gpmc,cs-on-ns = <0>;
@@ -296,7 +295,7 @@
 
 				#address-cells = <1>;
 				#size-cells = <1>;
-				elm_id = <&elm>;
+				ti,elm-id = <&elm>;
 
 				/* MTD partition table */
 				partition at 0 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index e2249bc..501f863 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -105,7 +105,7 @@
 		reg = <1 0 0x08000000>;
 		nand-bus-width = <8>;
 
-		ti,nand-ecc-opt = "sw";
+		ti,nand-ecc-opt = "ham1";
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <36>;
 		gpmc,cs-wr-off-ns = <36>;
-- 
1.8.1



From pekon at ti.com  Fri Oct 11 09:36:43 2013
From: pekon at ti.com (Pekon Gupta)
Date: Fri, 11 Oct 2013 19:06:43 +0530
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <1381498603-15715-7-git-send-email-pekon@ti.com>

"Managed Device Resource" or devm_xx calls takes care of automatic freeing
of the resource in case of:
- failure during driver probe
- failure during resource allocation
- detaching or unloading of driver module (rmmod)
Reference: Documentation/driver-model/devres.txt

Though OMAP NAND driver handles freeing of resource allocation in most of
the cases, but using devm_xx provides more clean and effortless approach
to handle all such cases.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 38 +++++++++++++++++++++-----------------
 1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a783dae..0f2b0d1 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1658,7 +1658,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
+				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -1690,13 +1691,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->phys_base = res->start;
 	info->mem_size = resource_size(res);
 
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
+	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
+				info->mem_size,	pdev->dev.driver->name)) {
 		err = -EBUSY;
 		goto out_free_info;
 	}
 
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	info->nand.IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
+						info->mem_size);
 	if (!info->nand.IO_ADDR_R) {
 		err = -ENOMEM;
 		goto out_release_mem_region;
@@ -1799,8 +1801,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 			err = -ENODEV;
 			goto out_release_mem_region;
 		}
-		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-fifo", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-fifo", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_fifo, err);
@@ -1814,8 +1817,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 			err = -ENODEV;
 			goto out_release_mem_region;
 		}
-		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-count", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-count", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_count, err);
@@ -2031,10 +2035,10 @@ out_release_mem_region:
 	if (info->dma)
 		dma_release_channel(info->dma);
 	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);
 	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);
+	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
 out_free_info:
 #ifdef CONFIG_MTD_NAND_ECC_BCH
 	if (info->nand.ecc.priv) {
@@ -2042,7 +2046,7 @@ out_free_info:
 		info->nand.ecc.priv = NULL;
 	}
 #endif
-	kfree(info);
+	devm_kfree(&pdev->dev, info);
 
 	return err;
 }
@@ -2062,15 +2066,15 @@ static int omap_nand_remove(struct platform_device *pdev)
 		dma_release_channel(info->dma);
 
 	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);
 	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
+		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);
 
 	/* Release NAND device, its internal structures and partitions */
 	nand_release(&info->mtd);
-	iounmap(info->nand.IO_ADDR_R);
-	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
+	devm_iounmap(&pdev->dev, info->nand.IO_ADDR_R);
+	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
+	devm_kfree(&pdev->dev, info);
 	return 0;
 }
 
-- 
1.8.1



From simon at liddicott.com  Fri Oct 11 09:57:56 2013
From: simon at liddicott.com (Simon Liddicott)
Date: Fri, 11 Oct 2013 14:57:56 +0100
Subject: nandsim LEB size mismatch
Message-ID: <CALuNSF7ESa0CBE0+kNO_HDeWKVgzN8ZZo7TnNGadTC0AuZjEXQ@mail.gmail.com>

Hi

I've searched the archives and read the FAQ but not found anything
that matches my situation.

I am trying to read an image I think is made for an MT29F2G08ABAEA.

I have run the following:

$ sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xda \
third_id_byte=0x90 fourth_id_byte=0x95
$ sudo flash_erase /dev/mtd0 0 0
$ sudo modprobe ubi mtd=0
$ sudo ubimkvol /dev/ubi0 -N RFS -s $((0xA00000))

Volume ID 0, size 82 LEBs (10579968 bytes, 10.1 MiB), LEB size 129024
bytes (126.0 KiB), dynamic, name "RFS", alignment 1

$ sudo ubiupdatevol /dev/ubi0_0 RFS.bin
$ sudo mount /dev/ubi0_0 /mnt

mount: wrong fs type, bad option, bad superblock on /dev/ubi0_0,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

[1975256.515179] UBIFS error (pid 10309): validate_sb: LEB size
mismatch: 126976 in superblock, 129024 real

I think that nandsim provides the 'real' value for LEB size, and even
if the value is right - how can I read the data that expects a 124KiB
LEB size?

Any help appreciated.

Thanks in advance.

Simon.


From balbi at ti.com  Fri Oct 11 11:55:36 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 10:55:36 -0500
Subject: [PATCH v8 1/6] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <1381498603-15715-2-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-2-git-send-email-pekon@ti.com>
Message-ID: <20131011155535.GQ25706@radagast>

On Fri, Oct 11, 2013 at 07:06:38PM +0530, Pekon Gupta wrote:
> OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
> ecc-scheme, like:
> - OMAP_ECC_HAMMING_CODE_DEFAULT
> 	1-bit hamming ecc code using software library
> - OMAP_ECC_HAMMING_CODE_HW
> 	1-bit hamming ecc-code using GPMC h/w engine
> - OMAP_ECC_HAMMING_CODE_HW_ROMCODE
> 	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
> 	to ROM code.
> 
> This patch combines above multiple ecc-schemes into single implementation:
> - OMAP_ECC_HAM1_CODE_HW
> 	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
> 	ecc-layout.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

Reviewed-by: Felipe Balbi <balbi at ti.com>

> ---
>  Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
>  arch/arm/mach-omap2/board-flash.c                   | 2 +-
>  arch/arm/mach-omap2/gpmc.c                          | 4 +---
>  drivers/mtd/nand/omap2.c                            | 9 +++------
>  include/linux/platform_data/mtd-nand-omap2.h        | 6 +-----
>  5 files changed, 10 insertions(+), 19 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> index df338cb..25ee232 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> @@ -22,10 +22,10 @@ Optional properties:
>  				width of 8 is assumed.
>  
>   - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
> -
> -		"sw"		Software method (default)
> -		"hw"		Hardware method
> -		"hw-romcode"	gpmc hamming mode method & romcode layout
> +		"sw"		<deprecated> use "ham1" instead
> +		"hw"		<deprecated> use "ham1" instead
> +		"hw-romcode"	<deprecated> use "ham1" instead
> +		"ham1"		1-bit Hamming ecc code
>  		"bch4"		4-bit BCH ecc code
>  		"bch8"		8-bit BCH ecc code
>  
> diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
> index fc20a61..ac82512 100644
> --- a/arch/arm/mach-omap2/board-flash.c
> +++ b/arch/arm/mach-omap2/board-flash.c
> @@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
>  	board_nand_data.nr_parts	= nr_parts;
>  	board_nand_data.devsize		= nand_type;
>  
> -	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
> +	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
>  	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/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 579697a..c9fb353 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1342,9 +1342,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  #ifdef CONFIG_MTD_NAND
>  
>  static const char * const nand_ecc_opts[] = {
> -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
> +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
>  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
>  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
>  };
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 4ecf0e5..8d521aa 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1993,10 +1993,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	}
>  
>  	/* select the ecc type */
> -	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
> -		info->nand.ecc.mode = NAND_ECC_SOFT;
> -	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
> -		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
> +	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
>  		info->nand.ecc.bytes            = 3;
>  		info->nand.ecc.size             = 512;
>  		info->nand.ecc.strength         = 1;
> @@ -2025,7 +2022,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	}
>  
>  	/* rom code layout */
> -	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
> +	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
>  
>  		if (info->nand.options & NAND_BUSWIDTH_16)
>  			offset = 2;
> @@ -2033,7 +2030,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  			offset = 1;
>  			info->nand.badblock_pattern = &bb_descrip_flashbased;
>  		}
> -		omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16);
> +		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
>  		for (i = 0; i < omap_oobinfo.eccbytes; i++)
>  			omap_oobinfo.eccpos[i] = i+offset;
>  
> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
> index 6bf9ef4..cb5a54a 100644
> --- a/include/linux/platform_data/mtd-nand-omap2.h
> +++ b/include/linux/platform_data/mtd-nand-omap2.h
> @@ -23,11 +23,7 @@ enum nand_io {
>  };
>  
>  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_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
>  	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
>  	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
>  };
> -- 
> 1.8.1
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/d63b237f/attachment-0001.sig>

From balbi at ti.com  Fri Oct 11 11:55:27 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 10:55:27 -0500
Subject: [PATCH v8 2/6] ARM: OMAP2+: cleaned-up DT support of various ECC
 schemes
In-Reply-To: <1381498603-15715-3-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-3-git-send-email-pekon@ti.com>
Message-ID: <20131011155527.GP25706@radagast>

On Fri, Oct 11, 2013 at 07:06:39PM +0530, Pekon Gupta wrote:
> OMAP NAND driver support multiple ECC scheme, which can used in following
> different flavours, depending on in-build Hardware engines supported by SoC.
> 
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
> |(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> |(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
> | ti,elm-id in DT)                      |               |               |
> +---------------------------------------+---------------+---------------+
> To optimize footprint of omap2-nand driver, selection of some ECC schemes
> also require enabling following Kconfigs, in addition to setting appropriate
> DT bindings
> - Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
> - Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine
> 
> DT binding updates in this patch are:
> - ti,elm-id: replaces elm_id
> - ti,nand-ecc-opts: supported values ham1, bch4, and bch8
> 	selection of h/w or s/w implementation depends on ti,elm-id
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

since this maintains backwards compatibility, I think it should be
alright to apply

Reviewed-by: Felipe Balbi <balbi at ti.com>

> ---
>  .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
>  arch/arm/mach-omap2/gpmc.c                         | 45 ++++++++++++++++------
>  include/linux/platform_data/mtd-nand-omap2.h       | 14 +++++--
>  3 files changed, 50 insertions(+), 17 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> index 25ee232..5e1f31b 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> @@ -36,8 +36,12 @@ Optional properties:
>  		"prefetch-dma"		Prefetch enabled sDMA mode
>  		"prefetch-irq"		Prefetch enabled irq mode
>  
> - - elm_id:	Specifies elm device node. This is required to support BCH
> - 		error correction using ELM module.
> + - elm_id:	<deprecated> use "ti,elm-id" instead
> + - ti,elm-id:	Specifies phandle of the ELM devicetree node.
> +		ELM is an on-chip hardware engine on TI SoC which is used for
> +		locating ECC errors for BCHx algorithms. SoC devices which have
> +		ELM hardware engines should specify this device node in .dtsi
> +		Using ELM for ECC error correction frees some CPU cycles.
>  
>  For inline partiton table parsing (optional):
>  
> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index c9fb353..9473c9f 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1341,12 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  
>  #ifdef CONFIG_MTD_NAND
>  
> -static const char * const nand_ecc_opts[] = {
> -	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> -	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> -	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> -};
> -
>  static const char * const nand_xfer_types[] = {
>  	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
>  	[NAND_OMAP_POLLED]			= "polled",
> @@ -1376,12 +1370,39 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
>  	gpmc_nand_data->cs = val;
>  	gpmc_nand_data->of_node = child;
>  
> -	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
> -		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
> -			if (!strcasecmp(s, nand_ecc_opts[val])) {
> -				gpmc_nand_data->ecc_opt = val;
> -				break;
> -			}
> +	/* Detect availability of ELM module */
> +	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
> +	if (gpmc_nand_data->elm_of_node == NULL)
> +		gpmc_nand_data->elm_of_node =
> +					of_parse_phandle(child, "elm_id", 0);
> +	if (gpmc_nand_data->elm_of_node == NULL)
> +		pr_warn("%s: ti,elm-id property not found\n", __func__);
> +
> +	/* select NAND ecc-opt */
> +	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
> +		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
> +		return -ENODEV;
> +	}
> +	if (!strcmp(s, "ham1") || !strcmp(s, "sw") ||
> +		!strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
> +		gpmc_nand_data->ecc_opt =
> +				OMAP_ECC_HAM1_CODE_HW;
> +	else if (!strcmp(s, "bch4"))
> +		if (gpmc_nand_data->elm_of_node)
> +			gpmc_nand_data->ecc_opt =
> +				OMAP_ECC_BCH4_CODE_HW;
> +		else
> +			gpmc_nand_data->ecc_opt =
> +				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
> +	else if (!strcmp(s, "bch8"))
> +		if (gpmc_nand_data->elm_of_node)
> +			gpmc_nand_data->ecc_opt =
> +				OMAP_ECC_BCH8_CODE_HW;
> +		else
> +			gpmc_nand_data->ecc_opt =
> +				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
> +	else
> +		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
>  
>  	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
>  		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
> diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
> index cb5a54a..4da5bfa 100644
> --- a/include/linux/platform_data/mtd-nand-omap2.h
> +++ b/include/linux/platform_data/mtd-nand-omap2.h
> @@ -23,9 +23,16 @@ enum nand_io {
>  };
>  
>  enum omap_ecc {
> -	OMAP_ECC_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
> -	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
> -	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
> +	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
> +	OMAP_ECC_HAM1_CODE_HW = 0,
> +	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
> +	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
> +	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
> +	OMAP_ECC_BCH4_CODE_HW,
> +	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
> +	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
> +	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
> +	OMAP_ECC_BCH8_CODE_HW,
>  };
>  
>  struct gpmc_nand_regs {
> @@ -59,5 +66,6 @@ struct omap_nand_platform_data {
>  
>  	/* for passing the partitions */
>  	struct device_node	*of_node;
> +	struct device_node	*elm_of_node;
>  };
>  #endif
> -- 
> 1.8.1
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/c33b14b4/attachment.sig>

From balbi at ti.com  Fri Oct 11 11:55:44 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 10:55:44 -0500
Subject: [PATCH v8 3/6] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <1381498603-15715-4-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-4-git-send-email-pekon@ti.com>
Message-ID: <20131011155544.GR25706@radagast>

On Fri, Oct 11, 2013 at 07:06:40PM +0530, Pekon Gupta wrote:
> OMAP NAND driver support multiple ECC scheme, which can used in following
> different flavours, depending on in-build Hardware engines supported by SoC.
> 
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
> |(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> |(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
> | ti,elm-id in DT)                      |               |               |
> +---------------------------------------+---------------+---------------+
> To optimize footprint of omap2-nand driver, selection of some ECC schemes
> also require enabling following Kconfigs, in addition to setting appropriate
> DT bindings
> - Kconfig:CONFIG_MTD_NAND_ECC_BCH        enables S/W based BCH ECC algorithm
> - Kconfig:CONFIG_MTD_NAND_OMAP_BCH       enables H/W based BCH ECC algorithm
> 
> This patch
> - separates the configurations code for each ECC schemes
> - fixes dependency issues based on Kconfig options
> - updates ELM device detection in is_elm_present()
> - cleans redundant code
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

Reviewed-by: Felipe Balbi <balbi at ti.com>

> ---
>  drivers/mtd/nand/omap2.c | 450 +++++++++++++++++++++++------------------------
>  1 file changed, 220 insertions(+), 230 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 8d521aa..fb96251 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -25,8 +25,10 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
>  #include <linux/bch.h>
> +#endif
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
>  #include <linux/platform_data/elm.h>
>  #endif
>  
> @@ -141,6 +143,9 @@
>  #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
>  #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
>  
> +#define BADBLOCK_MARKER_LENGTH		2
> +#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
> +
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
>  	0xac, 0x6b, 0xff, 0x99, 0x7b};
> @@ -182,14 +187,11 @@ struct omap_nand_info {
>  	u_char				*buf;
>  	int					buf_len;
>  	struct gpmc_nand_regs		reg;
> -
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> -	struct bch_control             *bch;
> -	struct nand_ecclayout           ecclayout;
> +	/* fields specific for BCHx_HW ECC scheme */
> +	struct bch_control              *bch;
>  	bool				is_elm_used;
>  	struct device			*elm_dev;
>  	struct device_node		*of_node;
> -#endif
>  };
>  
>  /**
> @@ -1058,8 +1060,7 @@ static int omap_dev_ready(struct mtd_info *mtd)
>  	}
>  }
>  
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> -
> +#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
>  /**
>   * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
>   * @mtd: MTD device structure
> @@ -1140,7 +1141,9 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
>  	/* Clear ecc and enable bits */
>  	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
>  }
> +#endif
>  
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
>  /**
>   * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
>   * @mtd: MTD device structure
> @@ -1225,7 +1228,9 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
>  
>  	return 0;
>  }
> +#endif /* CONFIG_MTD_NAND_ECC_BCH */
>  
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
>  /**
>   * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
>   * @mtd:	MTD device structure
> @@ -1517,7 +1522,9 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
>  
>  	return stat;
>  }
> +#endif /* CONFIG_MTD_NAND_OMAP_BCH */
>  
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
>  /**
>   * omap3_correct_data_bch - Decode received data and correct errors
>   * @mtd: MTD device structure
> @@ -1549,7 +1556,9 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
>  	}
>  	return count;
>  }
> +#endif /* CONFIG_MTD_NAND_ECC_BCH */
>  
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
>  /**
>   * omap_write_page_bch - BCH ecc based write page function for entire page
>   * @mtd:		mtd info structure
> @@ -1637,197 +1646,68 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
>  }
>  
>  /**
> - * omap3_free_bch - Release BCH ecc resources
> - * @mtd: MTD device structure
> + * is_elm_present - checks for presence of ELM module by scanning DT nodes
> + * @omap_nand_info: NAND device structure containing platform data
> + * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16
>   */
> -static void omap3_free_bch(struct mtd_info *mtd)
> +static int is_elm_present(struct omap_nand_info *info,
> +			struct device_node *elm_node, enum bch_ecc bch_type)
>  {
> -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> -						   mtd);
> -	if (info->bch) {
> -		free_bch(info->bch);
> -		info->bch = NULL;
> -	}
> -}
> -
> -/**
> - * omap3_init_bch - Initialize BCH ECC
> - * @mtd: MTD device structure
> - * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW)
> - */
> -static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
> -{
> -	int max_errors;
> -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> -						   mtd);
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH8
> -	const int hw_errors = BCH8_MAX_ERROR;
> -#else
> -	const int hw_errors = BCH4_MAX_ERROR;
> -#endif
> -	enum bch_ecc bch_type;
> -	const __be32 *parp;
> -	int lenp;
> -	struct device_node *elm_node;
> -
> -	info->bch = NULL;
> -
> -	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);
> -		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 = max_errors;
> -
> -	if (hw_errors == BCH8_MAX_ERROR)
> -		bch_type = BCH8_ECC;
> -	else
> -		bch_type = BCH4_ECC;
> -
> -	/* Detect availability of ELM module */
> -	parp = of_get_property(info->of_node, "elm_id", &lenp);
> -	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
> -		pr_err("Missing elm_id property, fall back to Software BCH\n");
> -		info->is_elm_used = false;
> -	} else {
> -		struct platform_device *pdev;
> -
> -		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
> -		pdev = of_find_device_by_node(elm_node);
> -		info->elm_dev = &pdev->dev;
> -
> -		if (elm_config(info->elm_dev, bch_type) == 0)
> -			info->is_elm_used = true;
> +	struct platform_device *pdev;
> +	info->is_elm_used = false;
> +	/* check whether elm-id is passed via DT */
> +	if (!elm_node) {
> +		pr_err("nand: error: ELM DT node not found\n");
> +		return -ENODEV;
>  	}
> -
> -	if (info->is_elm_used && (mtd->writesize <= 4096)) {
> -
> -		if (hw_errors == BCH8_MAX_ERROR)
> -			info->nand.ecc.bytes = BCH8_SIZE;
> -		else
> -			info->nand.ecc.bytes = BCH4_SIZE;
> -
> -		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;
> -	} else {
> -		/*
> -		 * 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;
> -		}
> +	pdev = of_find_device_by_node(elm_node);
> +	/* check whether ELM device is registered */
> +	if (!pdev) {
> +		pr_err("nand: error: ELM device not found\n");
> +		return -ENODEV;
>  	}
> -
> -	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
> +	/* ELM module available, now configure it */
> +	info->elm_dev = &pdev->dev;
> +	if (elm_config(info->elm_dev, bch_type))
> +		return -ENODEV;
> +	info->is_elm_used = true;
>  	return 0;
> -fail:
> -	omap3_free_bch(mtd);
> -	return -1;
>  }
> +#endif /* CONFIG_MTD_NAND_ECC_BCH */
>  
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
>  /**
> - * omap3_init_bch_tail - Build an oob layout for BCH ECC correction.
> + * omap3_free_bch - Release BCH ecc resources
>   * @mtd: MTD device structure
>   */
> -static int omap3_init_bch_tail(struct mtd_info *mtd)
> +static void omap3_free_bch(struct mtd_info *mtd)
>  {
> -	int i, steps, offset;
>  	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>  						   mtd);
> -	struct nand_ecclayout *layout = &info->ecclayout;
> -
> -	/* build oob layout */
> -	steps = mtd->writesize/info->nand.ecc.size;
> -	layout->eccbytes = steps*info->nand.ecc.bytes;
> -
> -	/* do not bother creating special oob layouts for small page devices */
> -	if (mtd->oobsize < 64) {
> -		pr_err("BCH ecc is not supported on small page devices\n");
> -		goto fail;
> -	}
> -
> -	/* reserve 2 bytes for bad block marker */
> -	if (layout->eccbytes+2 > mtd->oobsize) {
> -		pr_err("no oob layout available for oobsize %d eccbytes %u\n",
> -		       mtd->oobsize, layout->eccbytes);
> -		goto fail;
> +	if (info->bch) {
> +		free_bch(info->bch);
> +		info->bch = NULL;
>  	}
> -
> -	/* 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] = 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].length = mtd->oobsize-2-layout->eccbytes;
> -	info->nand.ecc.layout = layout;
> -
> -	if (!(info->nand.options & NAND_BUSWIDTH_16))
> -		info->nand.badblock_pattern = &bb_descrip_flashbased;
> -	return 0;
> -fail:
> -	omap3_free_bch(mtd);
> -	return -1;
>  }
>  
>  #else
> -static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
> -{
> -	pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n");
> -	return -1;
> -}
> -static int omap3_init_bch_tail(struct mtd_info *mtd)
> -{
> -	return -1;
> -}
> +
>  static void omap3_free_bch(struct mtd_info *mtd)
>  {
>  }
> -#endif /* CONFIG_MTD_NAND_OMAP_BCH */
> +#endif /* CONFIG_MTD_NAND_ECC_BCH */
>  
>  static int omap_nand_probe(struct platform_device *pdev)
>  {
>  	struct omap_nand_info		*info;
>  	struct omap_nand_platform_data	*pdata;
> +	struct mtd_info			*mtd;
> +	struct nand_chip		*nand_chip;
> +	struct nand_ecclayout		*ecclayout;
>  	int				err;
> -	int				i, offset;
> -	dma_cap_mask_t mask;
> -	unsigned sig;
> +	int				i;
> +	dma_cap_mask_t			mask;
> +	unsigned			sig;
>  	struct resource			*res;
>  	struct mtd_part_parser_data	ppdata = {};
>  
> @@ -1846,20 +1726,18 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	spin_lock_init(&info->controller.lock);
>  	init_waitqueue_head(&info->controller.wq);
>  
> -	info->pdev = pdev;
> -
> +	mtd			= &info->mtd;
> +	mtd->name		= dev_name(&pdev->dev);
> +	mtd->owner		= THIS_MODULE;
> +	mtd->priv		= &info->nand;
> +	nand_chip		= &info->nand;
> +	info->pdev		= pdev;
>  	info->gpmc_cs		= pdata->cs;
>  	info->reg		= pdata->reg;
> +	info->bch		= NULL;
>  
> -	info->mtd.priv		= &info->nand;
> -	info->mtd.name		= dev_name(&pdev->dev);
> -	info->mtd.owner		= THIS_MODULE;
> -
> -	info->nand.options	= pdata->devsize;
> -	info->nand.options	|= NAND_SKIP_BBTSCAN;
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
>  	info->of_node		= pdata->of_node;
> -#endif
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (res == NULL) {
> @@ -1903,6 +1781,30 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		info->nand.chip_delay = 50;
>  	}
>  
> +	/* scan NAND device conncted to controller */
> +	if (nand_scan_ident(mtd, 1, NULL)) {
> +		err = -ENXIO;
> +		goto out_release_mem_region;
> +	}
> +	pr_info("%s: detected %s NAND flash\n", DRIVER_NAME,
> +			(nand_chip->options & NAND_BUSWIDTH_16) ? "x16" : "x8");
> +	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
> +			(pdata->devsize & NAND_BUSWIDTH_16)) {
> +		pr_err("%s: but incorrectly configured as %s", DRIVER_NAME,
> +			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +	}
> +
> +	/* check for small page devices */
> +	if ((mtd->oobsize < 64) &&
> +		(pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
> +		pr_err("small page devices are not supported\n");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +	}
> +
> +	/* populate read & write API based on xfer_type selected */
>  	switch (pdata->xfer_type) {
>  	case NAND_OMAP_PREFETCH_POLLED:
>  		info->nand.read_buf   = omap_read_buf_pref;
> @@ -1992,61 +1894,148 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		goto out_release_mem_region;
>  	}
>  
> -	/* select the ecc type */
> -	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
> -		info->nand.ecc.bytes            = 3;
> -		info->nand.ecc.size             = 512;
> -		info->nand.ecc.strength         = 1;
> -		info->nand.ecc.calculate        = omap_calculate_ecc;
> -		info->nand.ecc.hwctl            = omap_enable_hwecc;
> -		info->nand.ecc.correct          = omap_correct_data;
> -		info->nand.ecc.mode             = NAND_ECC_HW;
> -	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
> -		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
> -		err = omap3_init_bch(&info->mtd, pdata->ecc_opt);
> -		if (err) {
> +	/* populate MTD interface based on ECC scheme */
> +	nand_chip->ecc.layout	= &omap_oobinfo;
> +	ecclayout		= &omap_oobinfo;
> +	switch (pdata->ecc_opt) {
> +	case OMAP_ECC_HAM1_CODE_HW:
> +		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
> +		nand_chip->ecc.mode             = NAND_ECC_HW;
> +		nand_chip->ecc.bytes            = 3;
> +		nand_chip->ecc.size             = 512;
> +		nand_chip->ecc.strength         = 1;
> +		nand_chip->ecc.calculate        = omap_calculate_ecc;
> +		nand_chip->ecc.hwctl            = omap_enable_hwecc;
> +		nand_chip->ecc.correct          = omap_correct_data;
> +		/* define custom ECC layout */
> +		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> +							(mtd->writesize /
> +							nand_chip->ecc.size);
> +		if (nand_chip->options & NAND_BUSWIDTH_16)
> +			ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
> +		else
> +			ecclayout->eccpos[0]	= 1;
> +		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
> +							ecclayout->eccbytes;
> +		break;
> +
> +	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
> +		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n");
> +		nand_chip->ecc.mode		= NAND_ECC_HW;
> +		nand_chip->ecc.size		= 512;
> +		nand_chip->ecc.bytes		= 7;
> +		nand_chip->ecc.strength		= 4;
> +		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> +		nand_chip->ecc.correct		= omap3_correct_data_bch;
> +		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
> +		/* define custom ECC layout */
> +		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> +							(mtd->writesize /
> +							nand_chip->ecc.size);
> +		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
> +		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
> +							ecclayout->eccbytes;
> +		/* software bch library is used for locating errors */
> +		info->bch = init_bch(nand_chip->ecc.bytes,
> +					nand_chip->ecc.strength,
> +					OMAP_ECC_BCH8_POLYNOMIAL);
> +		if (!info->bch) {
> +			pr_err("nand: error: unable to use s/w BCH library\n");
>  			err = -EINVAL;
> -			goto out_release_mem_region;
>  		}
> -	}
> +		break;
> +#else
> +		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +#endif
>  
> -	/* DIP switches on some boards change between 8 and 16 bit
> -	 * bus widths for flash.  Try the other width if the first try fails.
> -	 */
> -	if (nand_scan_ident(&info->mtd, 1, NULL)) {
> -		info->nand.options ^= NAND_BUSWIDTH_16;
> -		if (nand_scan_ident(&info->mtd, 1, NULL)) {
> -			err = -ENXIO;
> +	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
> +		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
> +		nand_chip->ecc.mode		= NAND_ECC_HW;
> +		nand_chip->ecc.size		= 512;
> +		nand_chip->ecc.bytes		= 13;
> +		nand_chip->ecc.strength		= 8;
> +		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> +		nand_chip->ecc.correct		= omap3_correct_data_bch;
> +		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
> +		/* define custom ECC layout */
> +		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> +							(mtd->writesize /
> +							nand_chip->ecc.size);
> +		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
> +		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
> +							ecclayout->eccbytes;
> +		/* software bch library is used for locating errors */
> +		info->bch = init_bch(nand_chip->ecc.bytes,
> +					nand_chip->ecc.strength,
> +					OMAP_ECC_BCH8_POLYNOMIAL);
> +		if (!info->bch) {
> +			pr_err("nand: error: unable to use s/w BCH library\n");
> +			err = -EINVAL;
>  			goto out_release_mem_region;
>  		}
> -	}
> -
> -	/* rom code layout */
> -	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
> +		break;
> +#else
> +		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +#endif
>  
> -		if (info->nand.options & NAND_BUSWIDTH_16)
> -			offset = 2;
> -		else {
> -			offset = 1;
> -			info->nand.badblock_pattern = &bb_descrip_flashbased;
> -		}
> -		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
> -		for (i = 0; i < omap_oobinfo.eccbytes; i++)
> -			omap_oobinfo.eccpos[i] = i+offset;
> -
> -		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
> -		omap_oobinfo.oobfree->length = info->mtd.oobsize -
> -					(offset + omap_oobinfo.eccbytes);
> -
> -		info->nand.ecc.layout = &omap_oobinfo;
> -	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
> -		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
> -		/* build OOB layout for BCH ECC correction */
> -		err = omap3_init_bch_tail(&info->mtd);
> -		if (err) {
> -			err = -EINVAL;
> +	case OMAP_ECC_BCH8_CODE_HW:
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n");
> +		nand_chip->ecc.mode		= NAND_ECC_HW;
> +		nand_chip->ecc.size		= 512;
> +		/* 14th bit is kept reserved for ROM-code compatibility */
> +		nand_chip->ecc.bytes		= 13 + 1;
> +		nand_chip->ecc.strength		= 8;
> +		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> +		nand_chip->ecc.correct		= omap_elm_correct_data;
> +		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
> +		nand_chip->ecc.read_page	= omap_read_page_bch;
> +		nand_chip->ecc.write_page	= omap_write_page_bch;
> +		/* This ECC scheme requires ELM H/W block */
> +		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
> +			pr_err("nand: error: could not initialize ELM\n");
>  			goto out_release_mem_region;
>  		}
> +		/* define custom ECC layout */
> +		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> +							(mtd->writesize /
> +							nand_chip->ecc.size);
> +		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
> +		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
> +							ecclayout->eccbytes;
> +		break;
> +#else
> +		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +#endif
> +
> +	default:
> +		pr_err("nand: error: invalid or unsupported ECC scheme\n");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +	}
> +
> +	/* populate remaining info for custom ecc layout */
> +	pr_info("%s: using custom ecc layout\n", DRIVER_NAME);
> +	ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH
> +						- ecclayout->eccbytes;
> +	if (!(nand_chip->options & NAND_BUSWIDTH_16))
> +		nand_chip->badblock_pattern = &bb_descrip_flashbased;
> +	for (i = 1; i < ecclayout->eccbytes; i++)
> +		ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
> +	/* check if NAND OOBSIZE meets ECC scheme requirement */
> +	if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
> +		pr_err("not enough OOB bytes required = %d, available=%d\n",
> +			ecclayout->eccbytes, mtd->oobsize);
> +		err = -EINVAL;
> +		goto out_release_mem_region;
>  	}
>  
>  	/* second phase scan */
> @@ -2072,6 +2061,7 @@ out_release_mem_region:
>  		free_irq(info->gpmc_irq_fifo, info);
>  	release_mem_region(info->phys_base, info->mem_size);
>  out_free_info:
> +	omap3_free_bch(&info->mtd);
>  	kfree(info);
>  
>  	return err;
> -- 
> 1.8.1
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/712437e6/attachment-0001.sig>

From balbi at ti.com  Fri Oct 11 11:55:53 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 10:55:53 -0500
Subject: [PATCH v8 4/6] mtd:nand:omap2: updated support for BCH4 ECC scheme
In-Reply-To: <1381498603-15715-5-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-5-git-send-email-pekon@ti.com>
Message-ID: <20131011155553.GS25706@radagast>

On Fri, Oct 11, 2013 at 07:06:41PM +0530, Pekon Gupta wrote:
> This patch adds following two flavours of BCH4 ECC scheme in omap2-nand driver
> - OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
> 	- uses GPMC H/W engine for calculating ECC.
> 	- uses software library (lib/bch.h & nand_bch.h) for error correction.
> 
> - OMAP_ECC_BCH4_CODE_HW
> 	- uses GPMC H/W engine for calculating ECC.
> 	- uses ELM H/W engine for error correction.
> 
> With this patch omap2-nand driver supports following ECC schemes:
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
> |OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> +---------------------------------------+---------------+---------------+
> Important:
> - Selection of OMAP_ECC_BCHx_CODE_HW_DETECTION_SW requires,
> 	Kconfig: CONFIG_MTD_NAND_ECC_BCH: enables S/W based BCH ECC algorithm.
> 
> - Selection of OMAP_ECC_BCHx_CODE_HW requires,
> 	Kconfig: CONFIG_MTD_NAND_OMAP_BCH: enables ELM H/W module.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

Reviewed-by: Felipe Balbi <balbi at ti.com>

> ---
>  drivers/mtd/nand/Kconfig |  30 ++---------
>  drivers/mtd/nand/omap2.c | 134 +++++++++++++++++++++--------------------------
>  2 files changed, 63 insertions(+), 101 deletions(-)
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index d885298..5836039 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
>  
>  config MTD_NAND_OMAP_BCH
>  	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
> -	tristate "Enable support for hardware BCH error correction"
> +	tristate "Support hardware based BCH error correction"
>  	default n
>  	select BCH
> -	select BCH_CONST_PARAMS
>  	help
> -	 Support for hardware BCH error correction.
> -
> -choice
> -	prompt "BCH error correction capability"
> -	depends on MTD_NAND_OMAP_BCH
> -
> -config MTD_NAND_OMAP_BCH8
> -	bool "8 bits / 512 bytes (recommended)"
> -	help
> -	 Support correcting up to 8 bitflips per 512-byte block.
> -	 This will use 13 bytes of spare area per 512 bytes of page data.
> -	 This is the recommended mode, as 4-bit mode does not work
> -	 on some OMAP3 revisions, due to a hardware bug.
> -
> -config MTD_NAND_OMAP_BCH4
> -	bool "4 bits / 512 bytes"
> -	help
> -	 Support correcting up to 4 bitflips per 512-byte block.
> -	 This will use 7 bytes of spare area per 512 bytes of page data.
> -	 Note that this mode does not work on some OMAP3 revisions, due to a
> -	 hardware bug. Please check your OMAP datasheet before selecting this
> -	 mode.
> -
> -endchoice
> +	  Some devices have built-in ELM hardware engine, which can be used to
> +	  locate and correct errors when using BCH ECC scheme. This enables the
> +	  driver support for same.
>  
>  if MTD_NAND_OMAP_BCH
>  config BCH_CONST_M
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index fb96251..a783dae 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -27,6 +27,7 @@
>  
>  #ifdef CONFIG_MTD_NAND_ECC_BCH
>  #include <linux/bch.h>
> +#include <linux/mtd/nand_bch.h>
>  #endif
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  #include <linux/platform_data/elm.h>
> @@ -144,7 +145,6 @@
>  #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
>  
>  #define BADBLOCK_MARKER_LENGTH		2
> -#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
>  
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
> @@ -188,7 +188,6 @@ struct omap_nand_info {
>  	int					buf_len;
>  	struct gpmc_nand_regs		reg;
>  	/* fields specific for BCHx_HW ECC scheme */
> -	struct bch_control              *bch;
>  	bool				is_elm_used;
>  	struct device			*elm_dev;
>  	struct device_node		*of_node;
> @@ -1522,43 +1521,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
>  
>  	return stat;
>  }
> -#endif /* CONFIG_MTD_NAND_OMAP_BCH */
>  
> -#ifdef CONFIG_MTD_NAND_ECC_BCH
> -/**
> - * omap3_correct_data_bch - Decode received data and correct errors
> - * @mtd: MTD device structure
> - * @data: page data
> - * @read_ecc: ecc read from nand flash
> - * @calc_ecc: ecc read from HW ECC registers
> - */
> -static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
> -				  u_char *read_ecc, u_char *calc_ecc)
> -{
> -	int i, count;
> -	/* cannot correct more than 8 errors */
> -	unsigned int errloc[8];
> -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> -						   mtd);
> -
> -	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
> -			   errloc);
> -	if (count > 0) {
> -		/* correct errors */
> -		for (i = 0; i < count; i++) {
> -			/* correct data only, not ecc bytes */
> -			if (errloc[i] < 8*512)
> -				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
> -			pr_debug("corrected bitflip %u\n", errloc[i]);
> -		}
> -	} else if (count < 0) {
> -		pr_err("ecc unrecoverable error\n");
> -	}
> -	return count;
> -}
> -#endif /* CONFIG_MTD_NAND_ECC_BCH */
> -
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
>  /**
>   * omap_write_page_bch - BCH ecc based write page function for entire page
>   * @mtd:		mtd info structure
> @@ -1675,28 +1638,6 @@ static int is_elm_present(struct omap_nand_info *info,
>  }
>  #endif /* CONFIG_MTD_NAND_ECC_BCH */
>  
> -#ifdef CONFIG_MTD_NAND_ECC_BCH
> -/**
> - * omap3_free_bch - Release BCH ecc resources
> - * @mtd: MTD device structure
> - */
> -static void omap3_free_bch(struct mtd_info *mtd)
> -{
> -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> -						   mtd);
> -	if (info->bch) {
> -		free_bch(info->bch);
> -		info->bch = NULL;
> -	}
> -}
> -
> -#else
> -
> -static void omap3_free_bch(struct mtd_info *mtd)
> -{
> -}
> -#endif /* CONFIG_MTD_NAND_ECC_BCH */
> -
>  static int omap_nand_probe(struct platform_device *pdev)
>  {
>  	struct omap_nand_info		*info;
> @@ -1731,10 +1672,10 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	mtd->owner		= THIS_MODULE;
>  	mtd->priv		= &info->nand;
>  	nand_chip		= &info->nand;
> +	nand_chip->ecc.priv	= NULL;
>  	info->pdev		= pdev;
>  	info->gpmc_cs		= pdata->cs;
>  	info->reg		= pdata->reg;
> -	info->bch		= NULL;
>  
>  	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
>  	info->of_node		= pdata->of_node;
> @@ -1927,7 +1868,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->ecc.bytes		= 7;
>  		nand_chip->ecc.strength		= 4;
>  		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> -		nand_chip->ecc.correct		= omap3_correct_data_bch;
> +		info->nand.ecc.correct		= nand_bch_correct_data;
>  		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
>  		/* define custom ECC layout */
>  		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> @@ -1937,10 +1878,11 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>  							ecclayout->eccbytes;
>  		/* software bch library is used for locating errors */
> -		info->bch = init_bch(nand_chip->ecc.bytes,
> -					nand_chip->ecc.strength,
> -					OMAP_ECC_BCH8_POLYNOMIAL);
> -		if (!info->bch) {
> +		info->nand.ecc.priv		= nand_bch_init(mtd,
> +							info->nand.ecc.size,
> +							info->nand.ecc.bytes,
> +							&info->nand.ecc.layout);
> +		if (!info->nand.ecc.priv) {
>  			pr_err("nand: error: unable to use s/w BCH library\n");
>  			err = -EINVAL;
>  		}
> @@ -1951,6 +1893,39 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		goto out_release_mem_region;
>  #endif
>  
> +	case OMAP_ECC_BCH4_CODE_HW:
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
> +		info->nand.ecc.mode		= NAND_ECC_HW;
> +		info->nand.ecc.size		= 512;
> +		/* 14th bit is kept reserved for ROM-code compatibility */
> +		info->nand.ecc.bytes		= 7 + 1;
> +		info->nand.ecc.strength		= 4;
> +		info->nand.ecc.hwctl		= omap3_enable_hwecc_bch;
> +		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;
> +		/* This ECC scheme requires ELM H/W block */
> +		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
> +			pr_err("nand: error: could not initialize ELM\n");
> +			err = -ENODEV;
> +			goto out_release_mem_region;
> +		}
> +		/* define ECC layout */
> +		ecclayout->eccbytes		= info->nand.ecc.bytes *
> +							(mtd->writesize /
> +							info->nand.ecc.size);
> +		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
> +		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
> +							ecclayout->eccbytes;
> +		break;
> +#else
> +		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +#endif
> +
>  	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
>  #ifdef CONFIG_MTD_NAND_ECC_BCH
>  		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
> @@ -1959,7 +1934,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->ecc.bytes		= 13;
>  		nand_chip->ecc.strength		= 8;
>  		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> -		nand_chip->ecc.correct		= omap3_correct_data_bch;
> +		info->nand.ecc.correct		= nand_bch_correct_data;
>  		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
>  		/* define custom ECC layout */
>  		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> @@ -1969,10 +1944,11 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>  							ecclayout->eccbytes;
>  		/* software bch library is used for locating errors */
> -		info->bch = init_bch(nand_chip->ecc.bytes,
> -					nand_chip->ecc.strength,
> -					OMAP_ECC_BCH8_POLYNOMIAL);
> -		if (!info->bch) {
> +		info->nand.ecc.priv		= nand_bch_init(mtd,
> +							info->nand.ecc.size,
> +							info->nand.ecc.bytes,
> +							&info->nand.ecc.layout);
> +		if (!info->nand.ecc.priv) {
>  			pr_err("nand: error: unable to use s/w BCH library\n");
>  			err = -EINVAL;
>  			goto out_release_mem_region;
> @@ -2023,7 +1999,6 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	}
>  
>  	/* populate remaining info for custom ecc layout */
> -	pr_info("%s: using custom ecc layout\n", DRIVER_NAME);
>  	ecclayout->oobfree->length = mtd->oobsize - BADBLOCK_MARKER_LENGTH
>  						- ecclayout->eccbytes;
>  	if (!(nand_chip->options & NAND_BUSWIDTH_16))
> @@ -2061,7 +2036,12 @@ out_release_mem_region:
>  		free_irq(info->gpmc_irq_fifo, info);
>  	release_mem_region(info->phys_base, info->mem_size);
>  out_free_info:
> -	omap3_free_bch(&info->mtd);
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
> +	if (info->nand.ecc.priv) {
> +		nand_bch_free(info->nand.ecc.priv);
> +		info->nand.ecc.priv = NULL;
> +	}
> +#endif
>  	kfree(info);
>  
>  	return err;
> @@ -2072,8 +2052,12 @@ static int omap_nand_remove(struct platform_device *pdev)
>  	struct mtd_info *mtd = platform_get_drvdata(pdev);
>  	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>  							mtd);
> -	omap3_free_bch(&info->mtd);
> -
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
> +	if (info->nand.ecc.priv) {
> +		nand_bch_free(info->nand.ecc.priv);
> +		info->nand.ecc.priv = NULL;
> +	}
> +#endif
>  	if (info->dma)
>  		dma_release_channel(info->dma);
>  
> -- 
> 1.8.1
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/25456107/attachment.sig>

From balbi at ti.com  Fri Oct 11 11:56:01 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 10:56:01 -0500
Subject: [PATCH v8 5/6] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1381498603-15715-6-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-6-git-send-email-pekon@ti.com>
Message-ID: <20131011155601.GT25706@radagast>

On Fri, Oct 11, 2013 at 07:06:42PM +0530, Pekon Gupta wrote:
> Updated DTS to replace deprecated binding with newer values
> Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

Reviewed-by: Felipe Balbi <balbi at ti.com>

> ---
>  arch/arm/boot/dts/am335x-evm.dts   | 3 +--
>  arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
> index e8ec875..1aee6ac 100644
> --- a/arch/arm/boot/dts/am335x-evm.dts
> +++ b/arch/arm/boot/dts/am335x-evm.dts
> @@ -269,7 +269,6 @@
>  				reg = <0 0 0>; /* CS0, offset 0 */
>  				nand-bus-width = <8>;
>  				ti,nand-ecc-opt = "bch8";
> -				gpmc,device-nand = "true";
>  				gpmc,device-width = <1>;
>  				gpmc,sync-clk-ps = <0>;
>  				gpmc,cs-on-ns = <0>;
> @@ -296,7 +295,7 @@
>  
>  				#address-cells = <1>;
>  				#size-cells = <1>;
> -				elm_id = <&elm>;
> +				ti,elm-id = <&elm>;
>  
>  				/* MTD partition table */
>  				partition at 0 {
> diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
> index e2249bc..501f863 100644
> --- a/arch/arm/boot/dts/omap3430-sdp.dts
> +++ b/arch/arm/boot/dts/omap3430-sdp.dts
> @@ -105,7 +105,7 @@
>  		reg = <1 0 0x08000000>;
>  		nand-bus-width = <8>;
>  
> -		ti,nand-ecc-opt = "sw";
> +		ti,nand-ecc-opt = "ham1";
>  		gpmc,cs-on-ns = <0>;
>  		gpmc,cs-rd-off-ns = <36>;
>  		gpmc,cs-wr-off-ns = <36>;
> -- 
> 1.8.1
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/cd9c25e3/attachment.sig>

From balbi at ti.com  Fri Oct 11 11:56:09 2013
From: balbi at ti.com (Felipe Balbi)
Date: Fri, 11 Oct 2013 10:56:09 -0500
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <1381498603-15715-7-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-7-git-send-email-pekon@ti.com>
Message-ID: <20131011155609.GU25706@radagast>

On Fri, Oct 11, 2013 at 07:06:43PM +0530, Pekon Gupta wrote:
> "Managed Device Resource" or devm_xx calls takes care of automatic freeing
> of the resource in case of:
> - failure during driver probe
> - failure during resource allocation
> - detaching or unloading of driver module (rmmod)
> Reference: Documentation/driver-model/devres.txt
> 
> Though OMAP NAND driver handles freeing of resource allocation in most of
> the cases, but using devm_xx provides more clean and effortless approach
> to handle all such cases.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

Reviewed-by: Felipe Balbi <balbi at ti.com>

> ---
>  drivers/mtd/nand/omap2.c | 38 +++++++++++++++++++++-----------------
>  1 file changed, 21 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index a783dae..0f2b0d1 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1658,7 +1658,8 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> -	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
> +	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
> +				GFP_KERNEL);
>  	if (!info)
>  		return -ENOMEM;
>  
> @@ -1690,13 +1691,14 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	info->phys_base = res->start;
>  	info->mem_size = resource_size(res);
>  
> -	if (!request_mem_region(info->phys_base, info->mem_size,
> -				pdev->dev.driver->name)) {
> +	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
> +				info->mem_size,	pdev->dev.driver->name)) {
>  		err = -EBUSY;
>  		goto out_free_info;
>  	}
>  
> -	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
> +	info->nand.IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
> +						info->mem_size);
>  	if (!info->nand.IO_ADDR_R) {
>  		err = -ENOMEM;
>  		goto out_release_mem_region;
> @@ -1799,8 +1801,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>  			err = -ENODEV;
>  			goto out_release_mem_region;
>  		}
> -		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
> -					IRQF_SHARED, "gpmc-nand-fifo", info);
> +		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
> +					omap_nand_irq, IRQF_SHARED,
> +					"gpmc-nand-fifo", info);
>  		if (err) {
>  			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
>  						info->gpmc_irq_fifo, err);
> @@ -1814,8 +1817,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>  			err = -ENODEV;
>  			goto out_release_mem_region;
>  		}
> -		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
> -					IRQF_SHARED, "gpmc-nand-count", info);
> +		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
> +					omap_nand_irq, IRQF_SHARED,
> +					"gpmc-nand-count", info);
>  		if (err) {
>  			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
>  						info->gpmc_irq_count, err);
> @@ -2031,10 +2035,10 @@ out_release_mem_region:
>  	if (info->dma)
>  		dma_release_channel(info->dma);
>  	if (info->gpmc_irq_count > 0)
> -		free_irq(info->gpmc_irq_count, info);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);
>  	if (info->gpmc_irq_fifo > 0)
> -		free_irq(info->gpmc_irq_fifo, info);
> -	release_mem_region(info->phys_base, info->mem_size);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);
> +	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
>  out_free_info:
>  #ifdef CONFIG_MTD_NAND_ECC_BCH
>  	if (info->nand.ecc.priv) {
> @@ -2042,7 +2046,7 @@ out_free_info:
>  		info->nand.ecc.priv = NULL;
>  	}
>  #endif
> -	kfree(info);
> +	devm_kfree(&pdev->dev, info);
>  
>  	return err;
>  }
> @@ -2062,15 +2066,15 @@ static int omap_nand_remove(struct platform_device *pdev)
>  		dma_release_channel(info->dma);
>  
>  	if (info->gpmc_irq_count > 0)
> -		free_irq(info->gpmc_irq_count, info);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);
>  	if (info->gpmc_irq_fifo > 0)
> -		free_irq(info->gpmc_irq_fifo, info);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);
>  
>  	/* Release NAND device, its internal structures and partitions */
>  	nand_release(&info->mtd);
> -	iounmap(info->nand.IO_ADDR_R);
> -	release_mem_region(info->phys_base, info->mem_size);
> -	kfree(info);
> +	devm_iounmap(&pdev->dev, info->nand.IO_ADDR_R);
> +	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
> +	devm_kfree(&pdev->dev, info);
>  	return 0;
>  }
>  
> -- 
> 1.8.1
> 

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131011/d10a63e5/attachment-0001.sig>

From computersforpeace at gmail.com  Fri Oct 11 14:15:15 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 11:15:15 -0700
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all
 resource allocation and free calls
In-Reply-To: <1381498603-15715-7-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-7-git-send-email-pekon@ti.com>
Message-ID: <20131011181515.GJ23337@ld-irv-0074.broadcom.com>

Hi Pekon,

On Fri, Oct 11, 2013 at 07:06:43PM +0530, Pekon Gupta wrote:
> "Managed Device Resource" or devm_xx calls takes care of automatic freeing
> of the resource in case of:
> - failure during driver probe
> - failure during resource allocation
> - detaching or unloading of driver module (rmmod)
> Reference: Documentation/driver-model/devres.txt
> 
> Though OMAP NAND driver handles freeing of resource allocation in most of
> the cases, but using devm_xx provides more clean and effortless approach
> to handle all such cases.

Judging by your patch, I think you missed the point of the devm_*
managed functions. They are useful because you don't need to do any of
the cleanup (kfree(), iounmap(), etc.) yourself. I'll note the changes
that are necessary below, but seeing as this is an add-on to your patch
series, I may merge the rest of series without this, and if so, you can
just resubmit this patch separately.

> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/omap2.c | 38 +++++++++++++++++++++-----------------
>  1 file changed, 21 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index a783dae..0f2b0d1 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1658,7 +1658,8 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> -	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
> +	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
> +				GFP_KERNEL);
>  	if (!info)
>  		return -ENOMEM;
>  
> @@ -1690,13 +1691,14 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	info->phys_base = res->start;
>  	info->mem_size = resource_size(res);
>  
> -	if (!request_mem_region(info->phys_base, info->mem_size,
> -				pdev->dev.driver->name)) {
> +	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
> +				info->mem_size,	pdev->dev.driver->name)) {
>  		err = -EBUSY;
>  		goto out_free_info;
>  	}
>  
> -	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
> +	info->nand.IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
> +						info->mem_size);
>  	if (!info->nand.IO_ADDR_R) {
>  		err = -ENOMEM;
>  		goto out_release_mem_region;
> @@ -1799,8 +1801,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>  			err = -ENODEV;
>  			goto out_release_mem_region;
>  		}
> -		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
> -					IRQF_SHARED, "gpmc-nand-fifo", info);
> +		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
> +					omap_nand_irq, IRQF_SHARED,
> +					"gpmc-nand-fifo", info);
>  		if (err) {
>  			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
>  						info->gpmc_irq_fifo, err);
> @@ -1814,8 +1817,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>  			err = -ENODEV;
>  			goto out_release_mem_region;
>  		}
> -		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
> -					IRQF_SHARED, "gpmc-nand-count", info);
> +		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
> +					omap_nand_irq, IRQF_SHARED,
> +					"gpmc-nand-count", info);
>  		if (err) {
>  			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
>  						info->gpmc_irq_count, err);
> @@ -2031,10 +2035,10 @@ out_release_mem_region:
>  	if (info->dma)
>  		dma_release_channel(info->dma);
>  	if (info->gpmc_irq_count > 0)
> -		free_irq(info->gpmc_irq_count, info);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);

Just drop the 'free'.

>  	if (info->gpmc_irq_fifo > 0)
> -		free_irq(info->gpmc_irq_fifo, info);
> -	release_mem_region(info->phys_base, info->mem_size);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);

Drop the 'free'.

> +	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);

Drop this line.

>  out_free_info:
>  #ifdef CONFIG_MTD_NAND_ECC_BCH
>  	if (info->nand.ecc.priv) {
> @@ -2042,7 +2046,7 @@ out_free_info:
>  		info->nand.ecc.priv = NULL;
>  	}
>  #endif
> -	kfree(info);
> +	devm_kfree(&pdev->dev, info);

This line is also not needed.

So in the end, the 'gotos' and error path of your probe function will be
much simpler. You will only need to manage the info->dma DMA channel
(i.e., dma_release_channel()).

>  
>  	return err;
>  }
> @@ -2062,15 +2066,15 @@ static int omap_nand_remove(struct platform_device *pdev)
>  		dma_release_channel(info->dma);
>  
>  	if (info->gpmc_irq_count > 0)
> -		free_irq(info->gpmc_irq_count, info);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_count, info);

This 'free' is also not needed.

>  	if (info->gpmc_irq_fifo > 0)
> -		free_irq(info->gpmc_irq_fifo, info);
> +		devm_free_irq(&pdev->dev, info->gpmc_irq_fifo, info);

Ditto.

>  
>  	/* Release NAND device, its internal structures and partitions */
>  	nand_release(&info->mtd);
> -	iounmap(info->nand.IO_ADDR_R);
> -	release_mem_region(info->phys_base, info->mem_size);
> -	kfree(info);
> +	devm_iounmap(&pdev->dev, info->nand.IO_ADDR_R);
> +	devm_release_mem_region(&pdev->dev, info->phys_base, info->mem_size);
> +	devm_kfree(&pdev->dev, info);

Ditto for all 3.

Your 'remove' function will also be much shorter.

>  	return 0;
>  }
>  

Thanks,
Brian


From computersforpeace at gmail.com  Fri Oct 11 14:16:15 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 11:16:15 -0700
Subject: [PATCH] [RESEND] mtd: docg4: fix status polling loop
In-Reply-To: <1381425927-1881-1-git-send-email-mikedunn@newsguy.com>
References: <1381425927-1881-1-git-send-email-mikedunn@newsguy.com>
Message-ID: <20131011181615.GK23337@ld-irv-0074.broadcom.com>

Hi Mike,

On Thu, Oct 10, 2013 at 10:25:27AM -0700, Mike Dunn wrote:
> The loop that polls the status register waiting for an operation to complete
> foolishly bases the timeout simply on the number of loop iterations that have
> ocurred.  When I increased the processor clock speed, timeouts started to appear
> for long block erasure operations.  This patch measures the timeout using
> jiffies.
> 
> Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
> ---
> 
> This is a rework of an earlier patch, based on Artem's recommendation to use
> jiffies, not udelay() (thanks Artem).  I didn't mark it 'v2' because the rework
> makes the original name of the patch inaccurate, so now it has a different name.
> 
> This was originally sent a couple months ago... was probably a bad time.

Wow, this identical patch was sent as far back as May 31 and is being
submitted for the 3rd time now :( I hope there will be fewer "bad times"
like this in the future.

Applied to l2-mtd.git. Thanks for the tenacity.

Is this -stable material, despite the long delay (pun unintended)?

Brian


From tony at atomide.com  Fri Oct 11 14:28:40 2013
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 11 Oct 2013 11:28:40 -0700
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all
 resource allocation and free calls
In-Reply-To: <20131011181515.GJ23337@ld-irv-0074.broadcom.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-7-git-send-email-pekon@ti.com>
 <20131011181515.GJ23337@ld-irv-0074.broadcom.com>
Message-ID: <20131011182840.GW29913@atomide.com>

* Brian Norris <computersforpeace at gmail.com> [131011 11:23]:
> Hi Pekon,
> 
> On Fri, Oct 11, 2013 at 07:06:43PM +0530, Pekon Gupta wrote:
> > "Managed Device Resource" or devm_xx calls takes care of automatic freeing
> > of the resource in case of:
> > - failure during driver probe
> > - failure during resource allocation
> > - detaching or unloading of driver module (rmmod)
> > Reference: Documentation/driver-model/devres.txt
> > 
> > Though OMAP NAND driver handles freeing of resource allocation in most of
> > the cases, but using devm_xx provides more clean and effortless approach
> > to handle all such cases.
> 
> Judging by your patch, I think you missed the point of the devm_*
> managed functions. They are useful because you don't need to do any of
> the cleanup (kfree(), iounmap(), etc.) yourself. I'll note the changes
> that are necessary below, but seeing as this is an add-on to your patch
> series, I may merge the rest of series without this, and if so, you can
> just resubmit this patch separately.

FYI, the .dts changes should be queued separately by Benoit to avoid
pointless merge conflicts. The arch/arm/mach-omap2/gpmc.c changes I
need to look, hopefully I can ack those for you today so you can take
the code related changes into the MTD tree.

Regards,

Tony


From mikedunn at newsguy.com  Fri Oct 11 14:31:18 2013
From: mikedunn at newsguy.com (Mike Dunn)
Date: Fri, 11 Oct 2013 11:31:18 -0700
Subject: [PATCH] [RESEND] mtd: docg4: fix status polling loop
In-Reply-To: <20131011181615.GK23337@ld-irv-0074.broadcom.com>
References: <1381425927-1881-1-git-send-email-mikedunn@newsguy.com>
 <20131011181615.GK23337@ld-irv-0074.broadcom.com>
Message-ID: <525843F6.8050907@newsguy.com>

On 10/11/2013 11:16 AM, Brian Norris wrote:
> Hi Mike,
> 
> On Thu, Oct 10, 2013 at 10:25:27AM -0700, Mike Dunn wrote:
>> The loop that polls the status register waiting for an operation to complete
>> foolishly bases the timeout simply on the number of loop iterations that have
>> ocurred.  When I increased the processor clock speed, timeouts started to appear
>> for long block erasure operations.  This patch measures the timeout using
>> jiffies.
>>
>> Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
>> ---
>>
>> This is a rework of an earlier patch, based on Artem's recommendation to use
>> jiffies, not udelay() (thanks Artem).  I didn't mark it 'v2' because the rework
>> makes the original name of the patch inaccurate, so now it has a different name.
>>
>> This was originally sent a couple months ago... was probably a bad time.
> 
> Wow, this identical patch was sent as far back as May 31 and is being
> submitted for the 3rd time now :( I hope there will be fewer "bad times"
> like this in the future.


Thanks much Brian.  No big deal.  There's only one other user of this driver
that I'm aware of :(

Thanks also for volunteering to shoulder some of the mtd maintenance duties.
Good job!

Mike



From tony at atomide.com  Fri Oct 11 14:32:34 2013
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 11 Oct 2013 11:32:34 -0700
Subject: [PATCH v8 2/6] ARM: OMAP2+: cleaned-up DT support of various
 ECC schemes
In-Reply-To: <20131011155527.GP25706@radagast>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-3-git-send-email-pekon@ti.com>
 <20131011155527.GP25706@radagast>
Message-ID: <20131011183234.GX29913@atomide.com>

* Felipe Balbi <balbi at ti.com> [131011 09:03]:
> On Fri, Oct 11, 2013 at 07:06:39PM +0530, Pekon Gupta wrote:
> > OMAP NAND driver support multiple ECC scheme, which can used in following
> > different flavours, depending on in-build Hardware engines supported by SoC.
> > 
> > +---------------------------------------+---------------+---------------+
> > | ECC scheme                            |ECC calculation|Error detection|
> > +---------------------------------------+---------------+---------------+
> > |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> > +---------------------------------------+---------------+---------------+
> > |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
> > |(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
> > +---------------------------------------+---------------+---------------+
> > |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> > |(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
> > | ti,elm-id in DT)                      |               |               |
> > +---------------------------------------+---------------+---------------+
> > To optimize footprint of omap2-nand driver, selection of some ECC schemes
> > also require enabling following Kconfigs, in addition to setting appropriate
> > DT bindings
> > - Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
> > - Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine
> > 
> > DT binding updates in this patch are:
> > - ti,elm-id: replaces elm_id
> > - ti,nand-ecc-opts: supported values ham1, bch4, and bch8
> > 	selection of h/w or s/w implementation depends on ti,elm-id
> > 
> > Signed-off-by: Pekon Gupta <pekon at ti.com>
> 
> since this maintains backwards compatibility, I think it should be
> alright to apply
> 
> Reviewed-by: Felipe Balbi <balbi at ti.com>

This patch looks safe to queue via the MTD tree for the arch/arm/*omap*
parts in this patch:

Acked-by: Tony Lindgren <tony at atomide.com>


From tony at atomide.com  Fri Oct 11 14:33:45 2013
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 11 Oct 2013 11:33:45 -0700
Subject: [PATCH v8 1/6] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <20131011155535.GQ25706@radagast>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-2-git-send-email-pekon@ti.com>
 <20131011155535.GQ25706@radagast>
Message-ID: <20131011183344.GY29913@atomide.com>

* Felipe Balbi <balbi at ti.com> [131011 09:04]:
> On Fri, Oct 11, 2013 at 07:06:38PM +0530, Pekon Gupta wrote:
> > OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
> > ecc-scheme, like:
> > - OMAP_ECC_HAMMING_CODE_DEFAULT
> > 	1-bit hamming ecc code using software library
> > - OMAP_ECC_HAMMING_CODE_HW
> > 	1-bit hamming ecc-code using GPMC h/w engine
> > - OMAP_ECC_HAMMING_CODE_HW_ROMCODE
> > 	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
> > 	to ROM code.
> > 
> > This patch combines above multiple ecc-schemes into single implementation:
> > - OMAP_ECC_HAM1_CODE_HW
> > 	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
> > 	ecc-layout.
> > 
> > Signed-off-by: Pekon Gupta <pekon at ti.com>
> 
> Reviewed-by: Felipe Balbi <balbi at ti.com>

This one looks safe to queue via the MTD tree for the arch/arm/*omap* parts:

Acked-by: Tony Lindgren <tony at atomide.com>


From robert.jarzmik at free.fr  Fri Oct 11 15:17:51 2013
From: robert.jarzmik at free.fr (Robert Jarzmik)
Date: Fri, 11 Oct 2013 21:17:51 +0200
Subject: [PATCH] mtg: docg3: use free_bch() instead of kfree()
In-Reply-To: <CAPgLHd_vT4cJ1F1a6TDzYb2LFSb-me90K58K22Z=ae3VsOfbng@mail.gmail.com>
 (Wei Yongjun's message of "Fri, 11 Oct 2013 12:40:21 +0800")
References: <CAPgLHd_vT4cJ1F1a6TDzYb2LFSb-me90K58K22Z=ae3VsOfbng@mail.gmail.com>
Message-ID: <878uxzy5uo.fsf@free.fr>

Wei Yongjun <weiyj.lk at gmail.com> writes:

> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
>
> Use free_bch() instead of kfree() to free init_bch()
> allocated data.
>
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
Acked-by: Robert Jarzmik <robert.jarzmik at free.fr>


From computersforpeace at gmail.com  Fri Oct 11 15:27:29 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 12:27:29 -0700
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <20131011182840.GW29913@atomide.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-7-git-send-email-pekon@ti.com>
 <20131011181515.GJ23337@ld-irv-0074.broadcom.com>
 <20131011182840.GW29913@atomide.com>
Message-ID: <CAN8TOE9S63a1YdtzS+urTGBoMqrhq83cXXEeGinvQi9=dyUX1Q@mail.gmail.com>

On Fri, Oct 11, 2013 at 11:28 AM, Tony Lindgren <tony at atomide.com> wrote:
> * Brian Norris <computersforpeace at gmail.com> [131011 11:23]:
>> Hi Pekon,
>>
>> On Fri, Oct 11, 2013 at 07:06:43PM +0530, Pekon Gupta wrote:
>> > "Managed Device Resource" or devm_xx calls takes care of automatic freeing
>> > of the resource in case of:
>> > - failure during driver probe
>> > - failure during resource allocation
>> > - detaching or unloading of driver module (rmmod)
>> > Reference: Documentation/driver-model/devres.txt
>> >
>> > Though OMAP NAND driver handles freeing of resource allocation in most of
>> > the cases, but using devm_xx provides more clean and effortless approach
>> > to handle all such cases.
>>
>> Judging by your patch, I think you missed the point of the devm_*
>> managed functions. They are useful because you don't need to do any of
>> the cleanup (kfree(), iounmap(), etc.) yourself. I'll note the changes
>> that are necessary below, but seeing as this is an add-on to your patch
>> series, I may merge the rest of series without this, and if so, you can
>> just resubmit this patch separately.
>
> FYI, the .dts changes should be queued separately by Benoit to avoid
> pointless merge conflicts. The arch/arm/mach-omap2/gpmc.c changes I
> need to look, hopefully I can ack those for you today so you can take
> the code related changes into the MTD tree.

Why are you replying to this patch, instead of the DTS?

Also, I don't think all of this code is ready. There are several
comments from weeks ago that Pekon hasn't addressed. It's possible the
DT binding changes can go in, but not some of the later patches, yet.

Brian


From computersforpeace at gmail.com  Fri Oct 11 15:28:33 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 12:28:33 -0700
Subject: [PATCH v8 3/6] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW
 ECC configurations in device_probe
In-Reply-To: <1381498603-15715-4-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-4-git-send-email-pekon@ti.com>
Message-ID: <20131011192833.GL23337@ld-irv-0074.broadcom.com>

On Fri, Oct 11, 2013 at 07:06:40PM +0530, Pekon Gupta wrote:
> OMAP NAND driver support multiple ECC scheme, which can used in following
> different flavours, depending on in-build Hardware engines supported by SoC.
> 
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
> |(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> |(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
> | ti,elm-id in DT)                      |               |               |
> +---------------------------------------+---------------+---------------+
> To optimize footprint of omap2-nand driver, selection of some ECC schemes
> also require enabling following Kconfigs, in addition to setting appropriate
> DT bindings
> - Kconfig:CONFIG_MTD_NAND_ECC_BCH        enables S/W based BCH ECC algorithm
> - Kconfig:CONFIG_MTD_NAND_OMAP_BCH       enables H/W based BCH ECC algorithm
> 
> This patch
> - separates the configurations code for each ECC schemes
> - fixes dependency issues based on Kconfig options
> - updates ELM device detection in is_elm_present()
> - cleans redundant code

I'll repeat my previous comment on this patch, since it seems entirely
ignored:

<quote>
[this patch] ... does too many unrelated things in a single patch. I am not
comfortable taking large amounts of refactoring mixed in with Kconfig
and #ifdef changes. Can you please separate the steps you list below
into multiple patches and describe each one? I think you are doing many
trivial things, but it's difficult to separate the noise out from the
substantial changes.
</quote>

Considering your frustration, it is certainly in your best interest to
make your patches more easily reviewable and to address my comments when
I make them. I cannot sign off on your patches in the current state, and
you have failed to properly address my comments on the nearly identical
code from weeks ago.

Please, put more effort into splitting your patches into reviewable
chunks and into writing *good* descriptions -- right now, 90% of your
commit message consists of a repeated ECC table, which does not actually
describe your changes. The remaining description is a jumble of multiple
unrelated thoughts, reflecting the similarly confusing patches. A
similar criticism applies to your other patches, whose descriptions do
not adequately reflect their contents.

> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/omap2.c | 450 +++++++++++++++++++++++------------------------
>  1 file changed, 220 insertions(+), 230 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 8d521aa..fb96251 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -25,8 +25,10 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
>  #include <linux/bch.h>
> +#endif
> +#ifdef CONFIG_MTD_NAND_OMAP_BCH
>  #include <linux/platform_data/elm.h>
>  #endif
>  

Why do you even need the #ifdef's for the #include's? It is not harmful
to include headers for stuff that is only conditionally used. In fact,
this creates a problem later when you try to use nand_bch_free(), and
you have to surround it with extra #ifdef's.

In short: these #ifdef's just breed more #ifdef's and cause the code to
become harder to read and less maintainable.

(I commented about the #ifdef's around nand_bch_free() in v6, and you
did not address the comment.)

> @@ -1846,20 +1726,18 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	spin_lock_init(&info->controller.lock);
>  	init_waitqueue_head(&info->controller.wq);
>  
> -	info->pdev = pdev;
> -
> +	mtd			= &info->mtd;
> +	mtd->name		= dev_name(&pdev->dev);
> +	mtd->owner		= THIS_MODULE;
> +	mtd->priv		= &info->nand;
> +	nand_chip		= &info->nand;
> +	info->pdev		= pdev;
>  	info->gpmc_cs		= pdata->cs;
>  	info->reg		= pdata->reg;
> +	info->bch		= NULL;
>  
> -	info->mtd.priv		= &info->nand;
> -	info->mtd.name		= dev_name(&pdev->dev);
> -	info->mtd.owner		= THIS_MODULE;
> -
> -	info->nand.options	= pdata->devsize;
> -	info->nand.options	|= NAND_SKIP_BBTSCAN;
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> +	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;

I recommended (in v6) you split the NAND_BUSWIDTH_AUTO change to a new
patch and to describe it in the commit. You did neither.

>  	info->of_node		= pdata->of_node;
> -#endif
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (res == NULL) {
> @@ -1903,6 +1781,30 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		info->nand.chip_delay = 50;
>  	}
>  
> +	/* scan NAND device conncted to controller */
> +	if (nand_scan_ident(mtd, 1, NULL)) {
> +		err = -ENXIO;
> +		goto out_release_mem_region;
> +	}
> +	pr_info("%s: detected %s NAND flash\n", DRIVER_NAME,
> +			(nand_chip->options & NAND_BUSWIDTH_16) ? "x16" : "x8");

I recommended you kill this in v6, and you did not address my comments.

> +	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
> +			(pdata->devsize & NAND_BUSWIDTH_16)) {
> +		pr_err("%s: but incorrectly configured as %s", DRIVER_NAME,
> +			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8");
> +		err = -EINVAL;
> +		goto out_release_mem_region;
...

Brian


From computersforpeace at gmail.com  Fri Oct 11 16:28:50 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 13:28:50 -0700
Subject: [PATCH v8 4/6] mtd:nand:omap2: updated support for BCH4 ECC scheme
In-Reply-To: <1381498603-15715-5-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-5-git-send-email-pekon@ti.com>
Message-ID: <20131011202850.GM23337@ld-irv-0074.broadcom.com>

On Fri, Oct 11, 2013 at 07:06:41PM +0530, Pekon Gupta wrote:
> This patch adds following two flavours of BCH4 ECC scheme in omap2-nand driver
> - OMAP_ECC_BCH4_CODE_HW_DETECTION_SW
> 	- uses GPMC H/W engine for calculating ECC.
> 	- uses software library (lib/bch.h & nand_bch.h) for error correction.
> 
> - OMAP_ECC_BCH4_CODE_HW
> 	- uses GPMC H/W engine for calculating ECC.
> 	- uses ELM H/W engine for error correction.
> 
> With this patch omap2-nand driver supports following ECC schemes:
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
> |OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> +---------------------------------------+---------------+---------------+
> Important:
> - Selection of OMAP_ECC_BCHx_CODE_HW_DETECTION_SW requires,
> 	Kconfig: CONFIG_MTD_NAND_ECC_BCH: enables S/W based BCH ECC algorithm.
> 
> - Selection of OMAP_ECC_BCHx_CODE_HW requires,
> 	Kconfig: CONFIG_MTD_NAND_OMAP_BCH: enables ELM H/W module.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/Kconfig |  30 ++---------
>  drivers/mtd/nand/omap2.c | 134 +++++++++++++++++++++--------------------------
>  2 files changed, 63 insertions(+), 101 deletions(-)
> 

...

> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index fb96251..a783dae 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1927,7 +1868,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->ecc.bytes		= 7;
>  		nand_chip->ecc.strength		= 4;
>  		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> -		nand_chip->ecc.correct		= omap3_correct_data_bch;
> +		info->nand.ecc.correct		= nand_bch_correct_data;

Your patch description doesn't talk about this (and the deletion of
omap3_correct_data_bch() above). Is the NAND BCH library a drop-in
replacement for omap3_correct_data_bch()? If so, TELL me about it in the
commit description. If not, this is an incompatible change and should at
least be documented so that people can understand the change. These
questions are being asked by the DT guys, so include it in your
descriptions.

Also, you're very inconsistent on using 'nand_chip' vs. 'info->nand'.
You added 'nand_chip' amid the noise of patch 3, so if you have it, use
it consistently throughout probe(). Or remove it and don't use it at
all. (This would be an independent patch from patch 3 and 4, in case
you're wondering, since it causes a lot of diff noise.)

>  		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
>  		/* define custom ECC layout */
>  		ecclayout->eccbytes		= nand_chip->ecc.bytes *

> @@ -2061,7 +2036,12 @@ out_release_mem_region:
>  		free_irq(info->gpmc_irq_fifo, info);
>  	release_mem_region(info->phys_base, info->mem_size);
>  out_free_info:
> -	omap3_free_bch(&info->mtd);
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
> +	if (info->nand.ecc.priv) {
> +		nand_bch_free(info->nand.ecc.priv);
> +		info->nand.ecc.priv = NULL;
> +	}
> +#endif

As noted previously, the #ifdef should not be necessary.

>  	kfree(info);
>  
>  	return err;
> @@ -2072,8 +2052,12 @@ static int omap_nand_remove(struct platform_device *pdev)
>  	struct mtd_info *mtd = platform_get_drvdata(pdev);
>  	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>  							mtd);
> -	omap3_free_bch(&info->mtd);
> -
> +#ifdef CONFIG_MTD_NAND_ECC_BCH
> +	if (info->nand.ecc.priv) {
> +		nand_bch_free(info->nand.ecc.priv);
> +		info->nand.ecc.priv = NULL;
> +	}
> +#endif

Ditto.

>  	if (info->dma)
>  		dma_release_channel(info->dma);
>  

Brian


From computersforpeace at gmail.com  Fri Oct 11 16:38:37 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 13:38:37 -0700
Subject: [PATCH] [RESEND] mtd: docg4: fix status polling loop
In-Reply-To: <525843F6.8050907@newsguy.com>
References: <1381425927-1881-1-git-send-email-mikedunn@newsguy.com>
 <20131011181615.GK23337@ld-irv-0074.broadcom.com>
 <525843F6.8050907@newsguy.com>
Message-ID: <20131011203837.GN23337@ld-irv-0074.broadcom.com>

On Fri, Oct 11, 2013 at 11:31:18AM -0700, Mike Dunn wrote:
> On 10/11/2013 11:16 AM, Brian Norris wrote:
> > On Thu, Oct 10, 2013 at 10:25:27AM -0700, Mike Dunn wrote:
> >> The loop that polls the status register waiting for an operation to complete
> >> foolishly bases the timeout simply on the number of loop iterations that have
> >> ocurred.  When I increased the processor clock speed, timeouts started to appear
> >> for long block erasure operations.  This patch measures the timeout using
> >> jiffies.
> >>
> >> Signed-off-by: Mike Dunn <mikedunn at newsguy.com>
> >> ---
> >>
> >> This is a rework of an earlier patch, based on Artem's recommendation to use
> >> jiffies, not udelay() (thanks Artem).  I didn't mark it 'v2' because the rework
> >> makes the original name of the patch inaccurate, so now it has a different name.
> >>
> >> This was originally sent a couple months ago... was probably a bad time.
> > 
> > Wow, this identical patch was sent as far back as May 31 and is being
> > submitted for the 3rd time now :( I hope there will be fewer "bad times"
> > like this in the future.
> 
> 
> Thanks much Brian.  No big deal.  There's only one other user of this driver
> that I'm aware of :(
> 
> Thanks also for volunteering to shoulder some of the mtd maintenance duties.
> Good job!

Thanks! It's an interesting job.

Brian


From computersforpeace at gmail.com  Fri Oct 11 17:09:24 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 14:09:24 -0700
Subject: [PATCH v8 0/6] mtd:nand:omap2: clean-up of supported ECC schemes
In-Reply-To: <1381498603-15715-1-git-send-email-pekon@ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
Message-ID: <20131011210924.GO23337@ld-irv-0074.broadcom.com>

Hi Pekon,

I will try to summarize the standing of your patch series.

Patches 1 and 2 look good and have addressed all of the DT maintainers'
comments, AFAICT. They are ready to go in, except that the following
patches are not ready; they should probably go in together.

You ignored most of my comments to patch 3, and it is insufficiently
documented. Please take a look at my comments, both here (in v8) and in
v6. It still should be split into more patches.

Patch 4 does too much without describing it. Why are you dropping the
old omap3_correct_data_bch() code? Is this just refactoring? If so, you
should say so. And this also suggests that you have two logical changes
going on that should be separated into different patches; one to
refactor the open-coded NAND/BCH library to replace it with the
nand_bch.{c,h} support library and one for the new ECC modes.

Patch 5 is good but should wait until the other DT parts are acceptable
and merged into MTD.

Patch 6 needs rewriting to use devm_* functions properly, but it was
never integral to this patch series. You can improve it and resend with
this series or just send it separately afterward.

On Fri, Oct 11, 2013 at 07:06:37PM +0530, Pekon Gupta wrote:
> *Changes v7 -> v8*
> [PATCH 1/6] <no updates>
> [PATCH 2/6]
> 	- updated DT parsing of "ti,nand-ecc-opts" so that its "ham1" remains
> 		compatible to "sw","hw","hw-romcode"
> 	- updated DT parsing of "ti,elm-id" to retain compatibility to "elm_id"
> 	- using of_parse_phandle() to get ELM device pointer from DT
> [PATCH 3..6/6] <commit log updates>
> 
> 
> *Changes v6 -> v7*
> [PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks of Brain Norris
> [PATCH 2/6] incorporated feedbacks from DT maintainers
> [PATCH 3/6] patch cleaning and incorporated feedbacks from Brain Norris

You did not incorporate most of my feedback here. Also, my name is
'Brian' not 'Brain', although I'm flattered ;)

> [PATCH 4/6] rebasing changes and cleanup
> [PATCH 5/6] updated omap3430-sdp.dts
> [PATCH 6/6] <NEW> updated for devm_xx

...

> After this patch series, omap2-nand driver will supports following ECC schemes:
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
> |OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.h)|
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> +---------------------------------------+---------------+---------------+
> 
> To optimize footprint of omap2-nand driver, selection of some ECC schemes
> also require enabling following Kconfigs, in addition to setting appropriate
> DT bindings
> - Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
> - Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine
> 
> 
> Pekon Gupta (6):
>   mtd: nand: omap: combine different flavours of 1-bit hamming ecc
>     schemes
>   ARM: OMAP2+: cleaned-up DT support of various ECC schemes
>   mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
>     device_probe
>   mtd:nand:omap2: updated support for BCH4 ECC scheme
>   ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
>   mtd: nand: omap: updated devm_xx for all resource allocation and free
>     calls
> 
>  .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
>  arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
>  arch/arm/mach-omap2/board-flash.c                  |   2 +-
>  arch/arm/mach-omap2/gpmc.c                         |  47 +-
>  drivers/mtd/nand/Kconfig                           |  30 +-
>  drivers/mtd/nand/omap2.c                           | 569 ++++++++++-----------
>  include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
>  8 files changed, 333 insertions(+), 354 deletions(-)

Brian


From computersforpeace at gmail.com  Fri Oct 11 17:19:51 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 14:19:51 -0700
Subject: [PATCH] mtg: docg3: use free_bch() instead of kfree()
In-Reply-To: <CAPgLHd_vT4cJ1F1a6TDzYb2LFSb-me90K58K22Z=ae3VsOfbng@mail.gmail.com>
References: <CAPgLHd_vT4cJ1F1a6TDzYb2LFSb-me90K58K22Z=ae3VsOfbng@mail.gmail.com>
Message-ID: <20131011211951.GP23337@ld-irv-0074.broadcom.com>

On Fri, Oct 11, 2013 at 12:40:21PM +0800, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> 
> Use free_bch() instead of kfree() to free init_bch()
> allocated data.
> 
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Pushed to l2-mtd.git. Thanks!

Brian


From tony at atomide.com  Fri Oct 11 17:46:54 2013
From: tony at atomide.com (Tony Lindgren)
Date: Fri, 11 Oct 2013 14:46:54 -0700
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all
 resource allocation and free calls
In-Reply-To: <CAN8TOE9S63a1YdtzS+urTGBoMqrhq83cXXEeGinvQi9=dyUX1Q@mail.gmail.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-7-git-send-email-pekon@ti.com>
 <20131011181515.GJ23337@ld-irv-0074.broadcom.com>
 <20131011182840.GW29913@atomide.com>
 <CAN8TOE9S63a1YdtzS+urTGBoMqrhq83cXXEeGinvQi9=dyUX1Q@mail.gmail.com>
Message-ID: <20131011214653.GA29913@atomide.com>

* Brian Norris <computersforpeace at gmail.com> [131011 12:35]:
> On Fri, Oct 11, 2013 at 11:28 AM, Tony Lindgren <tony at atomide.com> wrote:
> >
> > FYI, the .dts changes should be queued separately by Benoit to avoid
> > pointless merge conflicts. The arch/arm/mach-omap2/gpmc.c changes I
> > need to look, hopefully I can ack those for you today so you can take
> > the code related changes into the MTD tree.
> 
> Why are you replying to this patch, instead of the DTS?

Because you said you might merrge some parts of the series and I've
seen many merge cycles of pointless merge conflicts with driver
maintainers merging .dts files along with the driver changes? :)

Pekon, can please post the .dts changes entirely separately from
the driver changes in the future?
 
> Also, I don't think all of this code is ready. There are several
> comments from weeks ago that Pekon hasn't addressed. It's possible the
> DT binding changes can go in, but not some of the later patches, yet.

Yes that's up to you. I have not looked at the MTD parts and I
appreciate the fact that you are reviewing that stuff. I've acked
the arch/arm/*omap* parts so hopefully I'm out of the loop now.

Regards,

Tony


From computersforpeace at gmail.com  Fri Oct 11 18:14:43 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 15:14:43 -0700
Subject: [PATCH v8 6/6] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <20131011214653.GA29913@atomide.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-7-git-send-email-pekon@ti.com>
 <20131011181515.GJ23337@ld-irv-0074.broadcom.com>
 <20131011182840.GW29913@atomide.com>
 <CAN8TOE9S63a1YdtzS+urTGBoMqrhq83cXXEeGinvQi9=dyUX1Q@mail.gmail.com>
 <20131011214653.GA29913@atomide.com>
Message-ID: <CAN8TOE-0e+7211_c-Ao6RwP22ttKLSfVS54RQjHBiQxFtwS6PQ@mail.gmail.com>

On Fri, Oct 11, 2013 at 2:46 PM, Tony Lindgren <tony at atomide.com> wrote:
> * Brian Norris <computersforpeace at gmail.com> [131011 12:35]:
>> On Fri, Oct 11, 2013 at 11:28 AM, Tony Lindgren <tony at atomide.com> wrote:
>> >
>> > FYI, the .dts changes should be queued separately by Benoit to avoid
>> > pointless merge conflicts. The arch/arm/mach-omap2/gpmc.c changes I
>> > need to look, hopefully I can ack those for you today so you can take
>> > the code related changes into the MTD tree.
>>
>> Why are you replying to this patch, instead of the DTS?
>
> Because you said you might merrge some parts of the series and I've
> seen many merge cycles of pointless merge conflicts with driver
> maintainers merging .dts files along with the driver changes? :)

Sure, thanks for pointing this out. I may have fallen into that myself.

> Pekon, can please post the .dts changes entirely separately from
> the driver changes in the future?
>
>> Also, I don't think all of this code is ready. There are several
>> comments from weeks ago that Pekon hasn't addressed. It's possible the
>> DT binding changes can go in, but not some of the later patches, yet.
>
> Yes that's up to you. I have not looked at the MTD parts and I
> appreciate the fact that you are reviewing that stuff. I've acked
> the arch/arm/*omap* parts so hopefully I'm out of the loop now.

Yes, I think so. The MTD stuff is the only remaining weak point I see.

Brian


From computersforpeace at gmail.com  Fri Oct 11 18:24:59 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 11 Oct 2013 15:24:59 -0700
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
In-Reply-To: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
References: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
Message-ID: <20131011222459.GQ23337@ld-irv-0074.broadcom.com>

Hi Minal,

On Wed, Oct 09, 2013 at 05:05:11AM +0000, Shah, Minal wrote:
> I am using MTD utils version 1.5.0 for DRA7 (Vayu) platform.
> 
> I have bad blocks in some of my NAND partitions which I am not able to erase from linux kernel.

MTD does not allow erasing bad blocks. This is prohibited by NAND
datasheets. There are occasions where, for debugging purposes, one might
need to erase a "bad" block that is not actually bad, but MTD does not
provide an interface for doing this. An interface for doing so was
discussed a while back, but nothing was merged.

> Using "-N" option in flash_eraseall ideally should have allowed erasing the bad block but I land up in "MEMERASE64 ioctl failed" error. 

"-N" just means that the user-space tool (flash_erase) won't try to skip
bad blocks. But that doesn't circumvent the in-kernel protection that
prevents the erase from succeeding. So the "Input/output" error you see
is completely expected and currently unavoidable, unless you modify your
kernel to remove this protection.

[snip]

So why do you want to erase bad blocks?

Brian


From marex at denx.de  Fri Oct 11 21:17:11 2013
From: marex at denx.de (Marek Vasut)
Date: Sat, 12 Oct 2013 03:17:11 +0200
Subject: N25Q256A 13E40
In-Reply-To: <20131009214401.GD23337@ld-irv-0074.broadcom.com>
References: <201310071824.01028.marex@denx.de>
 <201310091214.02740.marex@denx.de>
 <20131009214401.GD23337@ld-irv-0074.broadcom.com>
Message-ID: <201310120317.12174.marex@denx.de>

Hi Brian,

Sorry for the late reply :(

> Hi,
> 
> On Wed, Oct 09, 2013 at 12:14:02PM +0200, Marek Vasut wrote:
> > > On Mon, Oct 7, 2013 at 9:24 AM, Marek Vasut <marex at denx.de> wrote:
> > > > Let's talk about our favourite chip :) I just got my hands on
> > > > N25Q256A . Since there was quite a flurry of patches for this and
> > > > similar chips and I got it working on a different chip with exactly
> > > > the same IDs and type, I'd would expect linux to work with this one
> > > > too. Guess what ... ;-)
> > > > 
> > > > This particular incarnation of N25Q256A completely ignores the 4-byte
> > > > ERASE (0xdc) command. Apparently, if I look closely, it's N25Q256A
> > > > 13E40 variant and seeing the Note #14 (datasheet page 30 / below
> > > > Table 18. Command set), quoting:
> > > > 
> > > > 14.This command is only for part numbers N25Q256A83ESF40x and
> > > > N25Q256A83E1240x.
> > > 
> > > This note also applies to PAGE_PROGRAM_4B (0x12) as well, right?
> > 
> > Yeah, both ERASE_4B and PP_4B or whatever they're called there.
> > Interestingly enough, READ_4B works ;-/
> 
> Well, the READ_4B consistency is (unintentionally?) helpful for my
> systems, as we have begun implementing a jumper switch so that the boot
> ROM will know whether to use FAST_READ or FAST_READ_4B. Since
> essentially all large SPI flash at *least* support the READ_4B command
> (as you noted), we can reliably boot from the flash, no matter what mode
> it is left in. After booting, we can choose the appropriate mode for
> programming/erasing.

I wish I had such a bootrom. In my case (freescale imx28), the bootrom can just 
do 3-byte operation and that's it. I believe the only way around here is to 
power-cycle the spi flash before the bootrom starts using it.

> > > [Now that I went back to look at some more code:] Wait, but we don't
> > > even try to use the 4-byte dedicated commands like 0xdc on Micron
> > > flash, so why are you having this problem? The code currently stands
> > 
> > > as:
> > The JEDEC_MFR for this flash Micron N25Q256A is CFI_MFR_ST (I wonder
> > why).
> 
> Probably some series of acquisitions?
> 
> But you didn't quite answer my question. Are you having problems with
> this Micron/ST/something-that's-not-AMD-or-Spansion flash using the
> current mainline? Or did you only have trouble when you tried modifying
> the code to use the dedicated 4-byte addressing commands?

Urgh, I just noticed I did exactly this. I modified the driver to enable this 4-
byte opcodes and then just forgot about it. Pardon my stupidity :(

Best regards,
Marek Vasut


From mike at robinson.net  Fri Oct 11 22:21:16 2013
From: mike at robinson.net (ek.gribova)
Date: Sat, 12 Oct 2013 04:21:16 +0200
Subject: =?windows-1251?Q?=ED=E0=F0=E0=F9=E8=E2=E0=E5=F2_=EE=E1=EC?=
 =?windows-1251?Q?=E5=ED_=E2=E5=F9=E5=F1=F2=E2?=
Message-ID: <CD052D10356D4AEFA4E72B084BEA8E56@fdwhhdl>

??????????? ??????? ?????? ? ????? http://nxy.in/onnkm

From ezequiel.garcia at free-electrons.com  Sat Oct 12 12:47:22 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 12 Oct 2013 13:47:22 -0300
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
In-Reply-To: <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
References: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
 <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
Message-ID: <20131012164721.GA22305@localhost>

On Fri, Oct 11, 2013 at 03:24:59PM -0700, Brian Norris wrote:
> Hi Minal,
> 
> On Wed, Oct 09, 2013 at 05:05:11AM +0000, Shah, Minal wrote:
> > I am using MTD utils version 1.5.0 for DRA7 (Vayu) platform.
> > 
> > I have bad blocks in some of my NAND partitions which I am not able to erase from linux kernel.
> 
> MTD does not allow erasing bad blocks. This is prohibited by NAND
> datasheets. There are occasions where, for debugging purposes, one might
> need to erase a "bad" block that is not actually bad, but MTD does not
> provide an interface for doing this. An interface for doing so was
> discussed a while back, but nothing was merged.
> 

Ah, interesting. As you know I'm doing some very intrusive debugging
while developing the Armada driver and I usually need to circumvent
(manually) the kernel bad block erase check. Sometimes my blocks are not
really bad, yet they are detected as bad.

I'd be interesting in having some way to remove the check easily, but
since this is of no benefit, unless you're developing a crazy driver
I'm not sure how to do this.

What do you think?

Maybe some hidden /sys/kernel/debug/mtd file to turn that option, just
for the use of a developer?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Sat Oct 12 18:26:17 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Sat, 12 Oct 2013 22:26:17 +0000
Subject: [PATCH v8 0/6] mtd:nand:omap2: clean-up of supported ECC schemes
In-Reply-To: <20131011210924.GO23337@ld-irv-0074.broadcom.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <20131011210924.GO23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2188A@DBDE04.ent.ti.com>

Hi Brain,

> 
> Hi Pekon,
> 
> I will try to summarize the standing of your patch series.
> 
> Patches 1 and 2 look good and have addressed all of the DT maintainers'
> comments, AFAICT. They are ready to go in, except that the following
> patches are not ready; they should probably go in together.
> 
> You ignored most of my comments to patch 3, and it is insufficiently
> documented. Please take a look at my comments, both here (in v8) and in
> v6. It still should be split into more patches.
> 
I tried splitting the earlier [PATCH 3/6], therefore a new patch for merging
various Hamming ECC schemes was spawned. But, I could not clean more
because I would have broken the NAND functionality in between the
patches.
My apologies, I missed some of you other comments, so I'm preparing
next version by splitting [PATCH 3/6] into more sub-patches for ease of
review. 
Most #ifdef were put to suppress warning of un-used functions during
compile time. So those cannot be removed, otherwise this patch would
give compile warnings under randconfig.


> Patch 4 does too much without describing it. Why are you dropping the
> old omap3_correct_data_bch() code? Is this just refactoring? If so, you
> should say so. And this also suggests that you have two logical changes
> going on that should be separated into different patches; one to
> refactor the open-coded NAND/BCH library to replace it with the
> nand_bch.{c,h} support library and one for the new ECC modes.
> 
Agreed, I update commit log to be more explicit that here nand_bch.c
actually encapsulates lib/bch.c.
Here also I cannot remove #ifdef across nand_bch_free() because
it frees some bch control data, which would not be defined for all
ecc-schemes (it is specific to xx_SW  ecc schemes). Hence removing
#ifdef here would give null-pointer exception.


> Patch 5 is good but should wait until the other DT parts are acceptable
> and merged into MTD.
> 
> Patch 6 needs rewriting to use devm_* functions properly, but it was
> never integral to this patch series. You can improve it and resend with
> this series or just send it separately afterward.
> 
Yes I understood this, but I think it would be still good to explicitly
free the resources in case of "module_remove()", because that would
free all resources instantaneously without waiting for devm_ to 
iterate thru the list when it wakes-up (I guess).

I'm not knowledgeable of exact implementation of devm_ and how
often does it iterates the list and frees the resources for corresponding
un-registered devices. So trusting you I'll include your feedbacks here.


with regards, pekon


From pekon at ti.com  Sat Oct 12 19:58:20 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Sat, 12 Oct 2013 23:58:20 +0000
Subject: [PATCH v8 3/6] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <20131011192833.GL23337@ld-irv-0074.broadcom.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-4-git-send-email-pekon@ti.com>
 <20131011192833.GL23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA218B5@DBDE04.ent.ti.com>

Hi Brian,

Thanks for such detailed review, please see some replies below..

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On Fri, Oct 11, 2013 at 07:06:40PM +0530, Pekon Gupta wrote:
[...]
> Why do you even need the #ifdef's for the #include's? It is not harmful
> to include headers for stuff that is only conditionally used. In fact,
> this creates a problem later when you try to use nand_bch_free(), and
> you have to surround it with extra #ifdef's.
> 
> In short: these #ifdef's just breed more #ifdef's and cause the code to
> become harder to read and less maintainable.
> 
There are 2 problems here:
(1) 
I have removed #ifdef across headers in next version. But I cannot remove
#ifdef across some callbacks for  cc.hwctl(), ecc.calculate(), ecc.correct(),
because then compilation would throw warnings for un-used functions.
(2)
OMAP driver uses generic lib/bch.c which is compiled only when
CONFIG_MTD_NAND_ECC_BCH is enabled. So to avoid compilation
issues, I had to put #ifdefs on all wrapper functions which use lib/bch.c
or nand_bch.c

I myself have tried in previous versions to avoid #ifdefs, but I ended
up in one or the other problem like (1) |  (2) above.
And this is where randconfig test failed earlier when Arnd Bergmann
commented, so some #ifdef would hv to be carried till be deprecate
some legacy ecc-schemes.
However, with patch split many redundant #ifdefs are now removed.


> (I commented about the #ifdef's around nand_bch_free() in v6, and you
> did not address the comment.)
> 
Done now.. My bad again, I somehow mis-interpreted nand_bch.c earlier.


> > @@ -1846,20 +1726,18 @@ static int omap_nand_probe(struct
> > -	info->nand.options	|= NAND_SKIP_BBTSCAN;
> > -#ifdef CONFIG_MTD_NAND_OMAP_BCH
> > +	nand_chip->options	|= NAND_SKIP_BBTSCAN |
> NAND_BUSWIDTH_AUTO;
> 
> I recommended (in v6) you split the NAND_BUSWIDTH_AUTO change to a
> new
> patch and to describe it in the commit. You did neither.
> 
Sorry missed this purposely because I could not separate out the changes.
But now I have re-worked this in next revision as a separate patch.


> > +	/* scan NAND device conncted to controller */
> > +	if (nand_scan_ident(mtd, 1, NULL)) {
> > +		err = -ENXIO;
> > +		goto out_release_mem_region;
> > +	}
> > +	pr_info("%s: detected %s NAND flash\n", DRIVER_NAME,
> > +			(nand_chip->options & NAND_BUSWIDTH_16) ?
> "x16" : "x8");
> 
> I recommended you kill this in v6, and you did not address my comments.
> 
Sorry, this was my bad.


with regards, pekon


From computersforpeace at gmail.com  Sat Oct 12 21:40:45 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Sat, 12 Oct 2013 18:40:45 -0700
Subject: [PATCH v8 0/6] mtd:nand:omap2: clean-up of supported ECC schemes
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2188A@DBDE04.ent.ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <20131011210924.GO23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2188A@DBDE04.ent.ti.com>
Message-ID: <5259FA1D.2090801@gmail.com>

Hi Pekon,

On 10/12/2013 03:26 PM, Gupta, Pekon wrote:

>> I will try to summarize the standing of your patch series.
>>
>> Patches 1 and 2 look good and have addressed all of the DT maintainers'
>> comments, AFAICT. They are ready to go in, except that the following
>> patches are not ready; they should probably go in together.
>>
>> You ignored most of my comments to patch 3, and it is insufficiently
>> documented. Please take a look at my comments, both here (in v8) and in
>> v6. It still should be split into more patches.
>>
> I tried splitting the earlier [PATCH 3/6], therefore a new patch for merging
> various Hamming ECC schemes was spawned. But, I could not clean more
> because I would have broken the NAND functionality in between the
> patches.

 From what I understand, your comment "cleans redundant code" in patch 3 
is entirely its own logical change; you're replacing the SW ECC in 
omap2.c with the library wrapper in lib/bch.c, right? So this should be 
described as such (as "replacing XXX with YYY") and can easily be its 
own patch?

Also, you add an 'mtd' and a 'nand_chip' (can you just call this 'chip' 
or maybe 'nand', like in other drivers?) variable to the probe function, 
and then partially convert the function over to inconsistently using mtd 
vs. info->mtd and nand_chip vs. info->nand. If you want to add these 
variables, just make it a separate patch.

I also mentioned your changes to the buswidth code, which seem to have 
snuck in again. This should be a separate patch.

> My apologies, I missed some of you other comments, so I'm preparing
> next version by splitting [PATCH 3/6] into more sub-patches for ease of
> review.

Great, thanks.

> Most #ifdef were put to suppress warning of un-used functions during
> compile time. So those cannot be removed, otherwise this patch would
> give compile warnings under randconfig.

Could be marked __maybe_unused instead? #ifdef's are also OK, if 
necessary. There were just a few places I pointed out that they was 
certainly not needed.

>> Patch 4 does too much without describing it. Why are you dropping the
>> old omap3_correct_data_bch() code? Is this just refactoring? If so, you
>> should say so. And this also suggests that you have two logical changes
>> going on that should be separated into different patches; one to
>> refactor the open-coded NAND/BCH library to replace it with the
>> nand_bch.{c,h} support library and one for the new ECC modes.
>>
> Agreed, I update commit log to be more explicit that here nand_bch.c
> actually encapsulates lib/bch.c.
> Here also I cannot remove #ifdef across nand_bch_free() because
> it frees some bch control data, which would not be defined for all
> ecc-schemes (it is specific to xx_SW  ecc schemes). Hence removing
> #ifdef here would give null-pointer exception.

Note that nand_bch_free() (and many others in nand_bch.h) are given 
empty inline implementation for CONFIG_MTD_NAND_ECC_BCH=n. But if you 
are unsure, then you can leave the #ifdef's to be conservative.

>> Patch 5 is good but should wait until the other DT parts are acceptable
>> and merged into MTD.
>>
>> Patch 6 needs rewriting to use devm_* functions properly, but it was
>> never integral to this patch series. You can improve it and resend with
>> this series or just send it separately afterward.
>>
> Yes I understood this, but I think it would be still good to explicitly
> free the resources in case of "module_remove()", because that would
> free all resources instantaneously without waiting for devm_ to
> iterate thru the list when it wakes-up (I guess).

devm_* is part of the driver core, so it does the cleanup immediately on 
a non-zero return from the probe() callback, or after exit from the 
remove() callback. It does not have to "wake up". Its only overhead is 
the small amount of memory used for the linked-list management.

Again, this is an optional piece of work, so don't worry about it too 
much. But you get 0 benefit (just a slight increase in memory usage) if 
you just convert all the kfree() calls to devm_kfree().

> I'm not knowledgeable of exact implementation of devm_ and how
> often does it iterates the list and frees the resources for corresponding
> un-registered devices. So trusting you I'll include your feedbacks here.

I haven't closely reviewed 100% of its implementation, but it is fairly 
straightforward and commonly used in many drivers. You should be fine 
using it as documented and recommended by me.

Thanks,
Brian


From computersforpeace at gmail.com  Sat Oct 12 21:40:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Sat, 12 Oct 2013 18:40:54 -0700
Subject: [PATCH v8 3/6] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA218B5@DBDE04.ent.ti.com>
References: <1381498603-15715-1-git-send-email-pekon@ti.com>
 <1381498603-15715-4-git-send-email-pekon@ti.com>
 <20131011192833.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA218B5@DBDE04.ent.ti.com>
Message-ID: <5259FA26.8090805@gmail.com>

Hi Pekon,

On 10/12/2013 04:58 PM, Gupta, Pekon wrote:
>> From: Brian Norris [mailto:computersforpeace at gmail.com]
>>> On Fri, Oct 11, 2013 at 07:06:40PM +0530, Pekon Gupta wrote:
> [...]
>> Why do you even need the #ifdef's for the #include's? It is not harmful
>> to include headers for stuff that is only conditionally used. In fact,
>> this creates a problem later when you try to use nand_bch_free(), and
>> you have to surround it with extra #ifdef's.
>>
>> In short: these #ifdef's just breed more #ifdef's and cause the code to
>> become harder to read and less maintainable.

First off, I should clarify this: the above comment was speaking *only* 
about surrounding the #include's with #ifdef's. Such #ifdef's only make 
everything else harder.

Now, I recognize that there are still many cases where you may need 
#ifdef's in the body of the code. I was only trying to hit the easiest ones.

> There are 2 problems here:
> (1)
> I have removed #ifdef across headers in next version. But I cannot remove
> #ifdef across some callbacks for  cc.hwctl(), ecc.calculate(), ecc.correct(),
> because then compilation would throw warnings for un-used functions.

The __maybe_unused attribute can be given to functions that will compile 
but are unused, and the compiler will just remove unused ones from the 
binary without warning. That is probably (weakly) preferable to 
#ifdef's, if you can manage it. But I understand some #ifdef's are 
necessary.

> (2)
> OMAP driver uses generic lib/bch.c which is compiled only when
> CONFIG_MTD_NAND_ECC_BCH is enabled. So to avoid compilation
> issues, I had to put #ifdefs on all wrapper functions which use lib/bch.c
> or nand_bch.c

nand_bch.c (and its corresponding nand_bch.h) has stub implementations 
so that extra #ifdef's often aren't needed. But include/linux/bch.h does 
not, so you are correct.

> I myself have tried in previous versions to avoid #ifdefs, but I ended
> up in one or the other problem like (1) |  (2) above.
> And this is where randconfig test failed earlier when Arnd Bergmann
> commented, so some #ifdef would hv to be carried till be deprecate
> some legacy ecc-schemes.
> However, with patch split many redundant #ifdefs are now removed.

Great, thanks for the effort.

Regards,
Brian


From michael.opdenacker at free-electrons.com  Sun Oct 13 02:21:32 2013
From: michael.opdenacker at free-electrons.com (Michael Opdenacker)
Date: Sun, 13 Oct 2013 08:21:32 +0200
Subject: [PATCH] mtd: nand: remove deprecated IRQF_DISABLED
Message-ID: <1381645292-9499-1-git-send-email-michael.opdenacker@free-electrons.com>

This patch proposes to remove the use of the IRQF_DISABLED flag

It's a NOOP since 2.6.35 and it will be removed one day.

Signed-off-by: Michael Opdenacker <michael.opdenacker at free-electrons.com>
---
 drivers/mtd/nand/mxc_nand.c    | 2 +-
 drivers/mtd/nand/pxa3xx_nand.c | 3 +--
 drivers/mtd/nand/tmio_nand.c   | 3 +--
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index ce8242b..58edc85 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -1507,7 +1507,7 @@ static int mxcnd_probe(struct platform_device *pdev)
 	host->devtype_data->irq_control(host, 0);
 
 	err = devm_request_irq(&pdev->dev, host->irq, mxc_nfc_irq,
-			IRQF_DISABLED, DRIVER_NAME, host);
+			0, DRIVER_NAME, host);
 	if (err)
 		return err;
 
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index dd03dfd..78a79a0 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1194,8 +1194,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
 	/* initialize all interrupts to be disabled */
 	disable_int(info, NDSR_MASK);
 
-	ret = request_irq(irq, pxa3xx_nand_irq, IRQF_DISABLED,
-			  pdev->name, info);
+	ret = request_irq(irq, pxa3xx_nand_irq, 0, pdev->name, info);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
 		goto fail_free_buf;
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index 396530d..a3747c9 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -428,8 +428,7 @@ static int tmio_probe(struct platform_device *dev)
 	/* 15 us command delay time */
 	nand_chip->chip_delay = 15;
 
-	retval = request_irq(irq, &tmio_irq,
-				IRQF_DISABLED, dev_name(&dev->dev), tmio);
+	retval = request_irq(irq, &tmio_irq, 0, dev_name(&dev->dev), tmio);
 	if (retval) {
 		dev_err(&dev->dev, "request_irq error %d\n", retval);
 		goto err_irq;
-- 
1.8.1.2



From hauke at hauke-m.de  Sun Oct 13 16:53:49 2013
From: hauke at hauke-m.de (Hauke Mehrtens)
Date: Sun, 13 Oct 2013 22:53:49 +0200
Subject: [PATCH] mtd: bcm47xxpart: handle malloc failures
Message-ID: <1381697629-31272-1-git-send-email-hauke@hauke-m.de>

Handle return NULL in malloc.

Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 drivers/mtd/bcm47xxpart.c |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index 9279a91..6d42746 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -71,7 +71,14 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 	/* Alloc */
 	parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
 			GFP_KERNEL);
+	if (!parts)
+		return -ENOMEM;
+
 	buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+	if (!buf) {
+		kfree(parts);
+		return -ENOMEM;
+	}
 
 	/* Parse block by block looking for magics */
 	for (offset = 0; offset <= master->size - blocksize;
-- 
1.7.10.4



From ezequiel.garcia at free-electrons.com  Sun Oct 13 17:05:23 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 13 Oct 2013 18:05:23 -0300
Subject: [PATCH] mtd: Move major number definitions to major.h
Message-ID: <1381698323-18932-1-git-send-email-ezequiel.garcia@free-electrons.com>

This patch moves the char and block major number definitions
to major.h to be with the rest of the major numbers.
While doing this, include major.h in the files that need it.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/devices/block2mtd.c | 1 +
 drivers/mtd/mtdblock.c          | 1 +
 drivers/mtd/mtdblock_ro.c       | 1 +
 drivers/mtd/mtdchar.c           | 1 +
 drivers/mtd/mtdcore.c           | 1 +
 drivers/mtd/mtdsuper.c          | 1 +
 drivers/mtd/ubi/build.c         | 1 +
 include/linux/mtd/mtd.h         | 3 ---
 include/uapi/linux/major.h      | 2 ++
 9 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 5cb4c04..d9fd87a 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -20,6 +20,7 @@
 #include <linux/mutex.h>
 #include <linux/mount.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 
 /* Info for the block device */
 struct block2mtd_dev {
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 53884cc..485ea75 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -32,6 +32,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
 #include <linux/mutex.h>
+#include <linux/major.h>
 
 
 struct mtdblk_dev {
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
index 70d27b4..fb5dc89 100644
--- a/drivers/mtd/mtdblock_ro.c
+++ b/drivers/mtd/mtdblock_ro.c
@@ -24,6 +24,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/blktrans.h>
 #include <linux/module.h>
+#include <linux/major.h>
 
 static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
 			      unsigned long block, char *buf)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..9aa0c5e 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -32,6 +32,7 @@
 #include <linux/mount.h>
 #include <linux/blkpg.h>
 #include <linux/magic.h>
+#include <linux/major.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 92311a5..7189089 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -37,6 +37,7 @@
 #include <linux/backing-dev.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index 334da5f..20c02a3 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -17,6 +17,7 @@
 #include <linux/export.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 
 /*
  * compare superblocks to see if they're equivalent
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 315dcc6..e05dc62 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -41,6 +41,7 @@
 #include <linux/kthread.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/major.h>
 #include "ubi.h"
 
 /* Maximum length of the 'mtd=' parameter */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 88409b8..8cc0e2f 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -29,9 +29,6 @@
 
 #include <asm/div64.h>
 
-#define MTD_CHAR_MAJOR 90
-#define MTD_BLOCK_MAJOR 31
-
 #define MTD_ERASE_PENDING	0x01
 #define MTD_ERASING		0x02
 #define MTD_ERASE_SUSPEND	0x04
diff --git a/include/uapi/linux/major.h b/include/uapi/linux/major.h
index 6a8ca98..620252e 100644
--- a/include/uapi/linux/major.h
+++ b/include/uapi/linux/major.h
@@ -54,6 +54,7 @@
 #define ACSI_MAJOR		28
 #define AZTECH_CDROM_MAJOR	29
 #define FB_MAJOR		29   /* /dev/fb* framebuffers */
+#define MTD_BLOCK_MAJOR		31
 #define CM206_CDROM_MAJOR	32
 #define IDE2_MAJOR		33
 #define IDE3_MAJOR		34
@@ -105,6 +106,7 @@
 #define IDE6_MAJOR		88
 #define IDE7_MAJOR		89
 #define IDE8_MAJOR		90
+#define MTD_CHAR_MAJOR		90
 #define IDE9_MAJOR		91
 
 #define DASD_MAJOR		94
-- 
1.8.1.5



From csc at google.com  Mon Oct 14 00:35:33 2013
From: csc at google.com (Google Inc)
Date: Mon, 14 Oct 2013 06:35:33 +0200
Subject: Hello User
Message-ID: <ae22cd6afb357ee7f76e94f77902beb0.squirrel@poczta.politechnika.koszalin.pl>




Dear Google User,
Congratulations for emerging as one of our winners, see attached document
for details.

Robert Jones,
P.R.O Google
-------------- next part --------------
A non-text attachment was scrubbed...
Name: GOOGLE+ AWARENESS REWARD.doc
Type: application/msword
Size: 87552 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131014/2d0a8de1/attachment-0001.doc>

From alexander.sverdlin at nsn.com  Mon Oct 14 12:52:23 2013
From: alexander.sverdlin at nsn.com (Alexander Sverdlin)
Date: Mon, 14 Oct 2013 18:52:23 +0200
Subject: [PATCH v2] mtd: phram: Repair multiple instances support
Message-ID: <525C2147.9060605@nsn.com>

mtd: phram: Repair multiple instances support

Commit b2a2a84d35e0f42ad26e326ec4258f6a8b8eecbe (mtd: phram: dot not crash when
built-in and passing boot param) claims to be "based on Ville Herva's similar
patch to block2mtd" (c4e7fb313771ac03dfdca26d30e8b721731c562b), but it has
missed the crucial point of the original path: all these "if(n)def MODULE".
It has broken the possibility to create several phram instances when phram is
compiled as module. The possibility to add instances via /sys writes to
/sys/module/phram/parameters/phram was also broken with mentioned patch.
Proposed patch takes the idea of original block2mtd patch to its full extent.
Assumtion "This function is always called before 'init_phram()'" was also
incorrect, so removed the comment. This patch effectively reverts also
b11ec57fc6e6d4882ef01a0c09a1dde58f50492e (mtd: phram: fix section mismatch for
phram_setup).

v2 changes: Fixed error handling in init_phram(). 

Signed-off-by: Alexander Sverdlin <alexander.sverdlin at nsn.com>

---
--- linux.orig/drivers/mtd/devices/phram.c
+++ linux/drivers/mtd/devices/phram.c
@@ -205,6 +205,8 @@ static inline void kill_final_newline(ch
 	return 1;		\
 } while (0)
 
+#ifndef MODULE
+static int phram_init_called = 0;
 /*
  * This shall contain the module parameter if any. It is of the form:
  * - phram=<device>,<address>,<size> for module case
@@ -213,9 +215,10 @@ static inline void kill_final_newline(ch
  * size.
  * Example: phram.phram=rootfs,0xa0000000,512Mi
  */
-static __initdata char phram_paramline[64 + 20 + 20];
+static char phram_paramline[64 + 20 + 20];
+#endif
 
-static int __init phram_setup(const char *val)
+static int phram_setup(const char *val)
 {
 	char buf[64 + 20 + 20], *str = buf;
 	char *token[3];
@@ -264,17 +267,36 @@ static int __init phram_setup(const char
 	return ret;
 }
 
-static int __init phram_param_call(const char *val, struct kernel_param *kp)
+static int phram_param_call(const char *val, struct kernel_param *kp)
 {
+#ifdef MODULE
+	return phram_setup(val);
+#else
 	/*
-	 * This function is always called before 'init_phram()', whether
-	 * built-in or module.
+	 * If more parameters are later passed in via
+	 * /sys/module/phram/parameters/phram
+	 * and init_phram() has already been called,
+	 * we can parse the argument now.
 	 */
+
+	if (phram_init_called)
+		return phram_setup(val);
+
+	/*
+	 * During early boot stage, we only save the parameters
+	 * here. We must parse them later: if the param passed
+	 * from kernel boot command line, phram_param_call() is
+	 * called so early that it is not possible to resolve
+	 * the device (even kmalloc() fails). Defer that work to
+	 * phram_setup().
+	 */
+
 	if (strlen(val) >= sizeof(phram_paramline))
 		return -ENOSPC;
 	strcpy(phram_paramline, val);
 
 	return 0;
+#endif
 }
 
 module_param_call(phram, phram_param_call, NULL, NULL, 000);
@@ -283,10 +305,15 @@ MODULE_PARM_DESC(phram, "Memory region t
 
 static int __init init_phram(void)
 {
+	int ret = 0;
+
+#ifndef MODULE
 	if (phram_paramline[0])
-		return phram_setup(phram_paramline);
+		ret = phram_setup(phram_paramline);
+	phram_init_called = 1;
+#endif
 
-	return 0;
+	return ret;
 }
 
 static void __exit cleanup_phram(void)


From rdunlap at infradead.org  Mon Oct 14 15:39:37 2013
From: rdunlap at infradead.org (Randy Dunlap)
Date: Mon, 14 Oct 2013 12:39:37 -0700
Subject: [PATCH -next] staging/mt29f_spinand: fix build error when ONDIEECC
 not enabled
In-Reply-To: <1381762088-18880-1-git-send-email-treding@nvidia.com>
References: <1381762088-18880-1-git-send-email-treding@nvidia.com>
Message-ID: <525C4879.4030705@infradead.org>

From: Randy Dunlap <rdunlap at infradead.org>

Fix build error when CONFIG_MTD_SPINAND_ONDIEECC is not enabled
by moving an inline function outside of that #ifdef block.

drivers/staging/mt29f_spinand/mt29f_spinand.c: In function 'spinand_read_byte':
drivers/staging/mt29f_spinand/mt29f_spinand.c:665:9: error: implicit declaration of function 'mtd_to_state' [-Werror=implicit-function-declaration]
drivers/staging/mt29f_spinand/mt29f_spinand.c:665:32: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/staging/mt29f_spinand/mt29f_spinand.c: In function 'spinand_write_buf':
drivers/staging/mt29f_spinand/mt29f_spinand.c:700:32: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/staging/mt29f_spinand/mt29f_spinand.c: In function 'spinand_read_buf':
drivers/staging/mt29f_spinand/mt29f_spinand.c:707:32: warning: initialization makes pointer from integer without a cast [enabled by default]

Signed-off-by: Randy Dunlap <rdunlap at infradead.org>
Cc: Kamlakant Patel <kamlakant.patel at broadcom.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Mona Anonuevo <manonuevo at micron.com>
Cc: linux-mtd at lists.infradead.org
---
 drivers/staging/mt29f_spinand/mt29f_spinand.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

--- next-2013-1014.orig/drivers/staging/mt29f_spinand/mt29f_spinand.c
+++ next-2013-1014/drivers/staging/mt29f_spinand/mt29f_spinand.c
@@ -28,9 +28,6 @@
 /*
  * OOB area specification layout:  Total 32 available free bytes.
  */
-#ifdef CONFIG_MTD_SPINAND_ONDIEECC
-static int enable_hw_ecc;
-static int enable_read_hw_ecc;
 
 static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd)
 {
@@ -41,6 +38,10 @@ static inline struct spinand_state *mtd_
 	return state;
 }
 
+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
+static int enable_hw_ecc;
+static int enable_read_hw_ecc;
+
 static struct nand_ecclayout spinand_oob_64 = {
 	.eccbytes = 24,
 	.eccpos = {


From ken at taxeducationinc.com  Mon Oct 14 15:34:05 2013
From: ken at taxeducationinc.com (ken at taxeducationinc.com)
Date: Mon, 14 Oct 2013 21:34:05 +0200
Subject: =?koi8-r?B?88HNz8Ug09fF0sjcxsbFy9TJ187PxSDT0sXE09TXzyDX?=
 =?koi8-r?B?IMTSwcvFINMgxM/Qz8zOydTFzNjO2c0g18XTz80=?=
Message-ID: <89765756.20131014215746@taxeducationinc.com>

??????? ? ????????? ????? http://agat-mk.com.ua/templates/atomic/ijnun.htm?EM


From B32167 at freescale.com  Tue Oct 15 00:32:41 2013
From: B32167 at freescale.com (Jain Priyanka-B32167)
Date: Tue, 15 Oct 2013 04:32:41 +0000
Subject: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <CAN8TOE9C1EumkFuWSqJD7+LeatsD5fk-mw8BM0ySZG-udcZC6A@mail.gmail.com>
References: <1378270016-9280-1-git-send-email-Priyanka.Jain@freescale.com>
 <201310022202.19877.marex@denx.de>
 <CAN8TOE8ii_fbz77M4HJBvyWwPxe+AGOh-sZW=rrwEKfxGhr61g@mail.gmail.com>
 <201310022255.01344.marex@denx.de>
 <CAN8TOE9C1EumkFuWSqJD7+LeatsD5fk-mw8BM0ySZG-udcZC6A@mail.gmail.com>
Message-ID: <AC83832D6324604BB08FAE5A33553F1915363DC3@039-SN2MPN1-012.039d.mgd.msft.net>

Thanks Brian,,Marek, 

I will make the correction and send the updated patch . 

Regards
Priyanka
> -----Original Message-----
> From: Brian Norris [mailto:computersforpeace at gmail.com]
> Sent: Thursday, October 03, 2013 2:32 AM
> To: Marek Vasut
> Cc: Jain Priyanka-B32167; Artem Bityutskiy; linux-mtd at lists.infradead.org
> Subject: Re: [PATCH] mtd: m25p80: Add support for Micron N25Q512A memory
> 
> On Wed, Oct 2, 2013 at 1:55 PM, Marek Vasut <marex at denx.de> wrote:
> > Dear Brian Norris,
> >
> >> On Wed, Oct 2, 2013 at 1:02 PM, Marek Vasut <marex at denx.de> wrote:
> >> > Hi Brian,
> >> >
> >> >>  + Marek for real!
> >> >>
> >> >> On Wed, Oct 2, 2013 at 11:51 AM, Brian Norris
> >> >>
> >> >> <computersforpeace at gmail.com> wrote:
> >> >> > + Marek
> >> >> >
> >> >> > On Wed, Sep 04, 2013 at 10:16:56AM +0530, Priyanka Jain wrote:
> >> >> >> Micron N25Q512A is a spi flash memory with following features:
> >> >> >> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
> >> >> >> -Memory is organised as 1024(64KB) main sectors.
> >> >> >> -Each sector is divided into 256 pages.
> >> >> >> -Register set/Opcodes are similar to other N25Q family products.
> >> >> >>
> >> >> >> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
> >> >> >> ---
> >> >> >>
> >> >> >>  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 26b14f9..94e3b53 100644
> >> >> >> --- a/drivers/mtd/devices/m25p80.c
> >> >> >> +++ b/drivers/mtd/devices/m25p80.c
> >> >> >> @@ -774,6 +774,7 @@ static const struct spi_device_id
> >> >> >> m25p_ids[] = {
> >> >> >>
> >> >> >>       { "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
> >> >> >>       { "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
> >> >> >>       { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K)
> >> >> >> },
> >> >> >>
> >> >> >> +     { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 512, SECT_4K)
> >> >> >> + },
> >> >
> >> > Why does this n25q256a and n25q512a have exactly the same geometry?
> >> > I mean, those chips differ in size, do they not ? ;-)
> >> >
> >> >> > This device actually has the same ID as Micron's next line
> >> >> > (MT25QL512A). They have the same geometry, so maybe that's not a
> >> >> > problem.
> >>
> >> I was referring to Micron n25q512a (which this patch mentions) and
> >> Micron's new generation of flash MT25QL512A (not mentioned in the
> >> original code or patch). They are different flash and are named
> >> differently but have the same ID. Perhaps my usage of the word "line"
> >> was confusing.
> >
> > Yes I know. Still, that n25q512a line being the exact copy of n25q256a
> > doesn't seem right.
> 
> Sorry, I didn't check the original patch carefully enough, and I
> subsequently misunderstood your question. I believe the patch is
> incorrect; it should be 512Mbit (64MByte) which makes it 64KB sector x
> 1024 number of sectors, not 64KB sector x 512 number of sectors. Good
> catch.
> 
> Priyanka, can you submit and test a corrected patch?
> 
> > The new ql512a seems line just a compatible replacement part for older
> lineup.
> > Happens all the time.
> 
> Hmm, OK.
> 
> Brian




From Priyanka.Jain at freescale.com  Tue Oct 15 01:39:05 2013
From: Priyanka.Jain at freescale.com (Priyanka Jain)
Date: Tue, 15 Oct 2013 11:09:05 +0530
Subject: [PATCH][v2] mtd: m25p80: Add support for Micron N25Q512A memory
Message-ID: <1381815545-4518-1-git-send-email-Priyanka.Jain@freescale.com>

Micron N25Q512A is a spi flash memory with following features:
-64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
-Memory is organised as 1024(64KB) main sectors.
-Each sector is divided into 256 pages.
-Register set/Opcodes are similar to other N25Q family products.

Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>
---
 Changes for v2:
	Corrected number of sectors to 1024 based on
	inputs from Marek Vasut and Brian Norris

 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 26b14f9..94e3b53 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
 	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
 	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+	{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
 
 	/* PMC */
 	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
-- 
1.7.4.1





From pekon at ti.com  Tue Oct 15 01:49:49 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:49 +0530
Subject: [PATCH v9 1/9] mtd: nand: omap: combine different flavours of 1-bit
 hamming ecc schemes
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-2-git-send-email-pekon@ti.com>

OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
ecc-scheme, like:
- OMAP_ECC_HAMMING_CODE_DEFAULT
	1-bit hamming ecc code using software library
- OMAP_ECC_HAMMING_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine
- OMAP_ECC_HAMMING_CODE_HW_ROMCODE
	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
	to ROM code.

This patch combines above multiple ecc-schemes into single implementation:
- OMAP_ECC_HAM1_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
	ecc-layout.

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
 arch/arm/mach-omap2/board-flash.c                   | 2 +-
 arch/arm/mach-omap2/gpmc.c                          | 4 +---
 drivers/mtd/nand/omap2.c                            | 9 +++------
 include/linux/platform_data/mtd-nand-omap2.h        | 6 +-----
 5 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index df338cb..25ee232 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -22,10 +22,10 @@ Optional properties:
 				width of 8 is assumed.
 
  - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-
-		"sw"		Software method (default)
-		"hw"		Hardware method
-		"hw-romcode"	gpmc hamming mode method & romcode layout
+		"sw"		<deprecated> use "ham1" instead
+		"hw"		<deprecated> use "ham1" instead
+		"hw-romcode"	<deprecated> use "ham1" instead
+		"ham1"		1-bit Hamming ecc code
 		"bch4"		4-bit BCH ecc code
 		"bch8"		8-bit BCH ecc code
 
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index fc20a61..ac82512 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
 
-	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
 	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/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 579697a..c9fb353 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1342,9 +1342,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 #ifdef CONFIG_MTD_NAND
 
 static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
-	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
-	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
+	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
 	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
 	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
 };
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..8d521aa 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1993,10 +1993,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
-		info->nand.ecc.mode = NAND_ECC_SOFT;
-	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
-		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 		info->nand.ecc.bytes            = 3;
 		info->nand.ecc.size             = 512;
 		info->nand.ecc.strength         = 1;
@@ -2025,7 +2022,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
 		if (info->nand.options & NAND_BUSWIDTH_16)
 			offset = 2;
@@ -2033,7 +2030,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			offset = 1;
 			info->nand.badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16);
+		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 6bf9ef4..cb5a54a 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,11 +23,7 @@ enum nand_io {
 };
 
 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_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
 	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
 	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
 };
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:48 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:48 +0530
Subject: [PATCH v9 0/9] mtd:nand:omap2: clean-up of supported ECC schemes
Message-ID: <1381816197-20477-1-git-send-email-pekon@ti.com>


*changes v8 -> v9*
[PATCH 1/9] <no update from [PATCH v8 1/6]>
[PATCH 2/9] <only commit log updated from [PATCH v8 2/6]>
 As per feedbacks from Brian Norris <computersforpeace at gmail.com> previous
 revision [PATCH v8 3/6] and [PATCH 4/6] are split into following sub-patches:
- [PATCH 3/9] <new> replaces local reference with generic names (mtd, nand_chip)
- [PATCH 4/9] <new> enables auto-detection of bus-width
- [PATCH 5/9] <new> removes omap3_init_bch: populates ecc-scheme data
- [PATCH 6/9] <new> removes omap3_init_bch_tail: populates ecc-layout
- [PATCH 7/9] <new> replaces lib/bch.c with nand_bch.c wrapper
[PATCH 8/9] <no update same as [PATCH v8 5/6]
[PATCH 9/9] removed devm_free_xx functions


*Changes v7 -> v8*
[PATCH 1/6] <no updates>
[PATCH 2/6]
	- updated DT parsing of "ti,nand-ecc-opts" so that its "ham1" remains
		compatible to "sw","hw","hw-romcode"
	- updated DT parsing of "ti,elm-id" to retain compatibility to "elm_id"
	- using of_parse_phandle() to get ELM device pointer from DT
[PATCH 3..6/6] <commit log updates>


*Changes v6 -> v7*
[PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks from Brian Norris <computersforpeace at gmail.com>
[PATCH 2/6] incorporated feedbacks from DT maintainers
[PATCH 3/6] cleaned and incorporated feedbacks from Brian Norris <computersforpeace at gmail.com>
[PATCH 4/6] rebasing changes and cleanup
[PATCH 5/6] updated omap3430-sdp.dts
[PATCH 6/6] <NEW> updated for devm_xx


*Changes v5 -> v6*
[PATCH 1/4]: 
	- updated DT binding for gpmc-nand based on 'Olof Johansson's feedbacks
	http://lists.infradead.org/pipermail/linux-mtd/2013-August/048394.html
	- detection of ELM device via ti,elm-id DT node, moved to gpmc.c driver
[PATCH 2/4]
	- removed: support for following obselete ECC schemes
	OMAP_ECC_HAMMING_CODE_DEFAULT (S/W based 1-bit Hamming ECC)
	OMAP_ECC_HAMMING_CODE_HW_ROMCODE (H/W based 1-bit Hamming ECC scheme)
	- updated: using omap_oobinfo as chip->ecc.layout for all ecc-schemes
	- clean: error messages
[PATCH 3/4] cleaned to include changes for OMAP_ECC_BCH8_CODE_HW only
[PATCH 4/4] updated to include DT property changes


*Changes v4 -> v5*
- Rebased to linux-next 
IMPORTANT: Need to revert commit fb1585b, [PATCH 2/4] part of previous version
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047441.html

- Swapped PATCH-1 & PATCH-2 to maintain bisectibility & compilation dependency
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047461.html

- PATCH-2: re-ordered call to is_elm_present() for later updates ELM driver
	- dropped changes in include/linux/platform_data/elm.h (not needed)
- PATCH-3: re-ordered call to is_elm_present() for later updates ELM driver
- Re-formated patch description (replaced tabs with white-spaces)


*Changes v3 -> v4*
(Resent with CC: devicetree-discuss at lists.ozlabs.org)
- [Patch 1/3] removed MTD_NAND_OMAP_BCH8 & MTD_NAND_OMAP_BCH4 from nand/Kconfig
	ECC scheme selectable via nand DT (nand-ecc-opt).
- [*] rebased for l2-mtd.git


*Changes v2 -> v3*
(Resent with Author Name fixed)
- PATCH-1: re-arranged code to remove redundancy, added NAND_BUSWIDTH_AUTO
- PATCH-2: updated nand-ecc-opt DT mapping and Documentation
- PATCH-3: code-cleaning + changes to match PATCH-1
- PATCH-4 <DROPPED> update DT attribute for ti,nand-ecc-opt 
	- received feedback to keep DT mapping independent of linuxism
- PATCH-4:<NEW> : ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
	- independent patch for AM335x-evm.dts update based on PATCH-2


*Changes v1 -> v2*
	added 	[PATCH 3/4] and [PATCH 4/4]


After this patch series, omap2-nand driver will supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+


Pekon Gupta (9):
  mtd: nand: omap: combine different flavours of 1-bit hamming ecc
    schemes
  ARM: OMAP2+: cleaned-up DT support of various ECC schemes
  mtd: nand: omap: cleanup: replace local references with generic
    framework names
  mtd: nand: omap: enable auto-detection of bus-width for omap-nand
    drivers
  mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
    device_probe
  mtd: nand: omap: clean-up ecc layout for BCH ecc schemes
  mtd: nand: omap: use drivers/mtd/nand/nand_bch.c wrapper for BCH ECC
    instead of lib/bch.c
  ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
  mtd: nand: omap: updated devm_xx for all resource allocation and free
    calls

 .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
 arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
 arch/arm/mach-omap2/board-flash.c                  |   2 +-
 arch/arm/mach-omap2/gpmc.c                         |  47 +-
 drivers/mtd/nand/Kconfig                           |  30 +-
 drivers/mtd/nand/omap2.c                           | 623 +++++++++------------
 include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
 8 files changed, 339 insertions(+), 402 deletions(-)

-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:51 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:51 +0530
Subject: [PATCH v9 3/9] mtd: nand: omap: cleanup: replace local references
 with generic framework names
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-4-git-send-email-pekon@ti.com>

This patch updates following in omap_nand_probe() and omap_nand_remove()
- replaces "info->nand" with "nand_chip" (struct nand_chip *nand_chip)
- replaces "info->mtd" with "mtd" (struct mtd_info *mtd)
- white-space and formatting cleanup

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 112 ++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 55 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8d521aa..5596368 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1824,10 +1824,12 @@ static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
 	struct omap_nand_platform_data	*pdata;
+	struct mtd_info			*mtd;
+	struct nand_chip		*nand_chip;
 	int				err;
 	int				i, offset;
-	dma_cap_mask_t mask;
-	unsigned sig;
+	dma_cap_mask_t			mask;
+	unsigned			sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
 
@@ -1846,17 +1848,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	spin_lock_init(&info->controller.lock);
 	init_waitqueue_head(&info->controller.wq);
 
-	info->pdev = pdev;
-
+	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-
-	info->mtd.priv		= &info->nand;
-	info->mtd.name		= dev_name(&pdev->dev);
-	info->mtd.owner		= THIS_MODULE;
-
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
+	mtd			= &info->mtd;
+	mtd->priv		= &info->nand;
+	mtd->name		= dev_name(&pdev->dev);
+	mtd->owner		= THIS_MODULE;
+	nand_chip		= &info->nand;
+	nand_chip->options	= pdata->devsize;
+	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
 #endif
@@ -1877,16 +1878,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_free_info;
 	}
 
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
-	if (!info->nand.IO_ADDR_R) {
+	nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	if (!nand_chip->IO_ADDR_R) {
 		err = -ENOMEM;
 		goto out_release_mem_region;
 	}
 
-	info->nand.controller = &info->controller;
+	nand_chip->controller = &info->controller;
 
-	info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
-	info->nand.cmd_ctrl  = omap_hwcontrol;
+	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
+	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
@@ -1896,26 +1897,26 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * device and read status register until you get a failure or success
 	 */
 	if (pdata->dev_ready) {
-		info->nand.dev_ready = omap_dev_ready;
-		info->nand.chip_delay = 0;
+		nand_chip->dev_ready = omap_dev_ready;
+		nand_chip->chip_delay = 0;
 	} else {
-		info->nand.waitfunc = omap_wait;
-		info->nand.chip_delay = 50;
+		nand_chip->waitfunc = omap_wait;
+		nand_chip->chip_delay = 50;
 	}
 
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
-		info->nand.read_buf   = omap_read_buf_pref;
-		info->nand.write_buf  = omap_write_buf_pref;
+		nand_chip->read_buf   = omap_read_buf_pref;
+		nand_chip->write_buf  = omap_write_buf_pref;
 		break;
 
 	case NAND_OMAP_POLLED:
-		if (info->nand.options & NAND_BUSWIDTH_16) {
-			info->nand.read_buf   = omap_read_buf16;
-			info->nand.write_buf  = omap_write_buf16;
+		if (nand_chip->options & NAND_BUSWIDTH_16) {
+			nand_chip->read_buf   = omap_read_buf16;
+			nand_chip->write_buf  = omap_write_buf16;
 		} else {
-			info->nand.read_buf   = omap_read_buf8;
-			info->nand.write_buf  = omap_write_buf8;
+			nand_chip->read_buf   = omap_read_buf8;
+			nand_chip->write_buf  = omap_write_buf8;
 		}
 		break;
 
@@ -1944,8 +1945,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 					err);
 				goto out_release_mem_region;
 			}
-			info->nand.read_buf   = omap_read_buf_dma_pref;
-			info->nand.write_buf  = omap_write_buf_dma_pref;
+			nand_chip->read_buf   = omap_read_buf_dma_pref;
+			nand_chip->write_buf  = omap_write_buf_dma_pref;
 		}
 		break;
 
@@ -1980,8 +1981,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 			goto out_release_mem_region;
 		}
 
-		info->nand.read_buf  = omap_read_buf_irq_pref;
-		info->nand.write_buf = omap_write_buf_irq_pref;
+		nand_chip->read_buf  = omap_read_buf_irq_pref;
+		nand_chip->write_buf = omap_write_buf_irq_pref;
 
 		break;
 
@@ -1994,16 +1995,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	/* select the ecc type */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-		info->nand.ecc.bytes            = 3;
-		info->nand.ecc.size             = 512;
-		info->nand.ecc.strength         = 1;
-		info->nand.ecc.calculate        = omap_calculate_ecc;
-		info->nand.ecc.hwctl            = omap_enable_hwecc;
-		info->nand.ecc.correct          = omap_correct_data;
-		info->nand.ecc.mode             = NAND_ECC_HW;
+		nand_chip->ecc.bytes            = 3;
+		nand_chip->ecc.size             = 512;
+		nand_chip->ecc.strength         = 1;
+		nand_chip->ecc.calculate        = omap_calculate_ecc;
+		nand_chip->ecc.hwctl            = omap_enable_hwecc;
+		nand_chip->ecc.correct          = omap_correct_data;
+		nand_chip->ecc.mode             = NAND_ECC_HW;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(&info->mtd, pdata->ecc_opt);
+		err = omap3_init_bch(mtd, pdata->ecc_opt);
 		if (err) {
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2013,9 +2014,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 	/* DIP switches on some boards change between 8 and 16 bit
 	 * bus widths for flash.  Try the other width if the first try fails.
 	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		nand_chip->options ^= NAND_BUSWIDTH_16;
+		if (nand_scan_ident(mtd, 1, NULL)) {
 			err = -ENXIO;
 			goto out_release_mem_region;
 		}
@@ -2024,25 +2025,25 @@ static int omap_nand_probe(struct platform_device *pdev)
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
-		if (info->nand.options & NAND_BUSWIDTH_16)
+		if (nand_chip->options & NAND_BUSWIDTH_16) {
 			offset = 2;
-		else {
+		} else {
 			offset = 1;
-			info->nand.badblock_pattern = &bb_descrip_flashbased;
+			nand_chip->badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
+		omap_oobinfo.eccbytes = 3 * (mtd->writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
 		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = info->mtd.oobsize -
+		omap_oobinfo.oobfree->length = mtd->oobsize -
 					(offset + omap_oobinfo.eccbytes);
 
-		info->nand.ecc.layout = &omap_oobinfo;
+		nand_chip->ecc.layout = &omap_oobinfo;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
 		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(&info->mtd);
+		err = omap3_init_bch_tail(mtd);
 		if (err) {
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2050,16 +2051,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* second phase scan */
-	if (nand_scan_tail(&info->mtd)) {
+	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
 		goto out_release_mem_region;
 	}
 
 	ppdata.of_node = pdata->of_node;
-	mtd_device_parse_register(&info->mtd, NULL, &ppdata, pdata->parts,
+	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
 				  pdata->nr_parts);
 
-	platform_set_drvdata(pdev, &info->mtd);
+	platform_set_drvdata(pdev, mtd);
 
 	return 0;
 
@@ -2080,9 +2081,10 @@ out_free_info:
 static int omap_nand_remove(struct platform_device *pdev)
 {
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(&info->mtd);
+	omap3_free_bch(mtd);
 
 	if (info->dma)
 		dma_release_channel(info->dma);
@@ -2093,8 +2095,8 @@ static int omap_nand_remove(struct platform_device *pdev)
 		free_irq(info->gpmc_irq_fifo, info);
 
 	/* Release NAND device, its internal structures and partitions */
-	nand_release(&info->mtd);
-	iounmap(info->nand.IO_ADDR_R);
+	nand_release(mtd);
+	iounmap(nand_chip->IO_ADDR_R);
 	release_mem_region(info->phys_base, info->mem_size);
 	kfree(info);
 	return 0;
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:50 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:50 +0530
Subject: [PATCH v9 2/9] ARM: OMAP2+: cleaned-up DT support of various ECC
 schemes
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-3-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in different
flavours, depending on in-build Hardware engines present on SoC.

This patch updates following in DT bindings related to sectionion of ecc-schemes
- ti,elm-id: replaces elm_id (maintains backward compatibility)
- ti,nand-ecc-opts: selection of h/w or s/w implementation of an ecc-scheme
	depends on ti,elm-id. (supported values ham1, bch4, and bch8)
- maintain backward compatibility to deprecated DT bindings (sw, hw, hw-romcode)

Below table shows different flavours of ecc-schemes supported by OMAP devices
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+

To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
 arch/arm/mach-omap2/gpmc.c                         | 45 ++++++++++++++++------
 include/linux/platform_data/mtd-nand-omap2.h       | 14 +++++--
 3 files changed, 50 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 25ee232..5e1f31b 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -36,8 +36,12 @@ Optional properties:
 		"prefetch-dma"		Prefetch enabled sDMA mode
 		"prefetch-irq"		Prefetch enabled irq mode
 
- - elm_id:	Specifies elm device node. This is required to support BCH
- 		error correction using ELM module.
+ - elm_id:	<deprecated> use "ti,elm-id" instead
+ - ti,elm-id:	Specifies phandle of the ELM devicetree node.
+		ELM is an on-chip hardware engine on TI SoC which is used for
+		locating ECC errors for BCHx algorithms. SoC devices which have
+		ELM hardware engines should specify this device node in .dtsi
+		Using ELM for ECC error correction frees some CPU cycles.
 
 For inline partiton table parsing (optional):
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c9fb353..9473c9f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1341,12 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 
 #ifdef CONFIG_MTD_NAND
 
-static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
-	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
-	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
-};
-
 static const char * const nand_xfer_types[] = {
 	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
 	[NAND_OMAP_POLLED]			= "polled",
@@ -1376,12 +1370,39 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 	gpmc_nand_data->cs = val;
 	gpmc_nand_data->of_node = child;
 
-	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-			if (!strcasecmp(s, nand_ecc_opts[val])) {
-				gpmc_nand_data->ecc_opt = val;
-				break;
-			}
+	/* Detect availability of ELM module */
+	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		gpmc_nand_data->elm_of_node =
+					of_parse_phandle(child, "elm_id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		pr_warn("%s: ti,elm-id property not found\n", __func__);
+
+	/* select NAND ecc-opt */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!strcmp(s, "ham1") || !strcmp(s, "sw") ||
+		!strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
+		gpmc_nand_data->ecc_opt =
+				OMAP_ECC_HAM1_CODE_HW;
+	else if (!strcmp(s, "bch4"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	else if (!strcmp(s, "bch8"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	else
+		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
 
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
 		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index cb5a54a..4da5bfa 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,9 +23,16 @@ enum nand_io {
 };
 
 enum omap_ecc {
-	OMAP_ECC_HAM1_CODE_HW = 0, /* 1-bit Hamming ecc code */
-	OMAP_ECC_BCH4_CODE_HW, /* 4-bit BCH ecc code */
-	OMAP_ECC_BCH8_CODE_HW, /* 8-bit BCH ecc code */
+	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_HAM1_CODE_HW = 0,
+	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH4_CODE_HW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH8_CODE_HW,
 };
 
 struct gpmc_nand_regs {
@@ -59,5 +66,6 @@ struct omap_nand_platform_data {
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
+	struct device_node	*elm_of_node;
 };
 #endif
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:52 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:52 +0530
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of bus-width
 for omap-nand drivers
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-5-git-send-email-pekon@ti.com>

Autodetection of NAND device bus-width was added in generic NAND driver as
part of following commit
	commit 64b37b2a63eb2f80b65c7185f0013f8ffc637ae3
	Author:     Matthieu CASTET <matthieu.castet at parrot.com>
	AuthorDate: 2012-11-06
	mtd: nand: add NAND_BUSWIDTH_AUTO to autodetect bus width
This patch enables this feature for OMAP2 NAND driver

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5596368..57a3f51 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1856,8 +1856,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
-	nand_chip->options	= pdata->devsize;
-	nand_chip->options	|= NAND_SKIP_BBTSCAN;
+	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
 #endif
@@ -1904,6 +1903,21 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->chip_delay = 50;
 	}
 
+	/* scan for NAND device connected to chip controller */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		err = -ENXIO;
+		goto out_release_mem_region;
+	}
+	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
+			(pdata->devsize & NAND_BUSWIDTH_16)) {
+		pr_err("%s: detected %s device but driver configured for %s\n",
+			DRIVER_NAME,
+			(nand_chip->options & NAND_BUSWIDTH_16) ? "x16" : "x8",
+			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		nand_chip->read_buf   = omap_read_buf_pref;
@@ -2011,17 +2025,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(mtd, 1, NULL)) {
-		nand_chip->options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(mtd, 1, NULL)) {
-			err = -ENXIO;
-			goto out_release_mem_region;
-		}
-	}
-
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:53 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:53 +0530
Subject: [PATCH v9 5/9] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-6-git-send-email-pekon@ti.com>

current implementation in omap3_init_bch() has some redundant code like:
(1) omap3_init_bch() re-probes the DT-binding to detect presence of ELM h/w
    engine on SoC. And based on that it selects implemetation of ecc-scheme.
    However, this is already done as part of GPMC DT parsing.
(2) As omap3_init_bch() serves as common function for configuring all types of
    BCHx ecc-schemes, so there are multiple levels of redudant if..then..else
    checks while populating nand_chip->ecc.

This patch make following changes to OMAP NAND driver:
(1) removes omap3_init_bch(): each ecc-scheme is individually configured in
    omap_nand_probe() there by removing redundant if..then..else checks.
(2) adds is_elm_present(): re-probing of ELM device via DT is not required as
    it's done in GPMC driver probe. Thus is_elm_present() just initializes ELM
    driver with NAND probe data, when ecc-scheme with h/w based error-detection
    is used.
(3) separates out configuration of different flavours of "BCH4" and "BCH8"
    ecc-schemes as given in below table
(4) conditionally compiles callbacks implementations of ecc.hwctl(),
    ecc.calculate(), ecc.correct() to avoid warning of un-used functions.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+

- 'CONFIG_MTD_NAND_ECC_BCH' is generic KConfig required to build lib/bch.c
    which is required for ECC error detection done in software.
    (mainly used for legacy platforms which do not have on-chip ELM engine)

- 'CONFIG_MTD_NAND_OMAP_BCH' is OMAP specific Kconfig to detemine presence
    on ELM h/w engine on SoC.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 281 ++++++++++++++++++++++++++---------------------
 1 file changed, 158 insertions(+), 123 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 57a3f51..09ce85c 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,10 +25,8 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/bch.h>
 #include <linux/platform_data/elm.h>
-#endif
 
 #include <linux/platform_data/mtd-nand-omap2.h>
 
@@ -141,6 +139,8 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
+
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 	0xac, 0x6b, 0xff, 0x99, 0x7b};
@@ -182,14 +182,12 @@ struct omap_nand_info {
 	u_char				*buf;
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	/* fields specific for BCHx_HW ECC scheme */
 	struct bch_control             *bch;
 	struct nand_ecclayout           ecclayout;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
-#endif
 };
 
 /**
@@ -1058,8 +1056,7 @@ static int omap_dev_ready(struct mtd_info *mtd)
 	}
 }
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
  * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
  * @mtd: MTD device structure
@@ -1140,7 +1137,9 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	/* Clear ecc and enable bits */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
+#endif
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
  * @mtd: MTD device structure
@@ -1225,7 +1224,9 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 
 	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1517,7 +1518,9 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
+#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_correct_data_bch - Decode received data and correct errors
  * @mtd: MTD device structure
@@ -1549,7 +1552,9 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
 	}
 	return count;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1637,118 +1642,48 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
+ * is_elm_present - checks for presence of ELM module by scanning DT nodes
+ * @omap_nand_info: NAND device structure containing platform data
+ * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16
  */
-static void omap3_free_bch(struct mtd_info *mtd)
+static int is_elm_present(struct omap_nand_info *info,
+			struct device_node *elm_node, enum bch_ecc bch_type)
 {
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
+	struct platform_device *pdev;
+	info->is_elm_used = false;
+	/* check whether elm-id is passed via DT */
+	if (!elm_node) {
+		pr_err("nand: error: ELM DT node not found\n");
+		return -ENODEV;
+	}
+	pdev = of_find_device_by_node(elm_node);
+	/* check whether ELM device is registered */
+	if (!pdev) {
+		pr_err("nand: error: ELM device not found\n");
+		return -ENODEV;
 	}
+	/* ELM module available, now configure it */
+	info->elm_dev = &pdev->dev;
+	if (elm_config(info->elm_dev, bch_type))
+		return -ENODEV;
+	info->is_elm_used = true;
+	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
- * omap3_init_bch - Initialize BCH ECC
+ * omap3_free_bch - Release BCH ecc resources
  * @mtd: MTD device structure
- * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW)
  */
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
+static void omap3_free_bch(struct mtd_info *mtd)
 {
-	int max_errors;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-#ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = BCH8_MAX_ERROR;
-#else
-	const int hw_errors = BCH4_MAX_ERROR;
-#endif
-	enum bch_ecc bch_type;
-	const __be32 *parp;
-	int lenp;
-	struct device_node *elm_node;
-
-	info->bch = NULL;
-
-	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);
-		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 = max_errors;
-
-	if (hw_errors == BCH8_MAX_ERROR)
-		bch_type = BCH8_ECC;
-	else
-		bch_type = BCH4_ECC;
-
-	/* Detect availability of ELM module */
-	parp = of_get_property(info->of_node, "elm_id", &lenp);
-	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
-		pr_err("Missing elm_id property, fall back to Software BCH\n");
-		info->is_elm_used = false;
-	} else {
-		struct platform_device *pdev;
-
-		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
-		pdev = of_find_device_by_node(elm_node);
-		info->elm_dev = &pdev->dev;
-
-		if (elm_config(info->elm_dev, bch_type) == 0)
-			info->is_elm_used = true;
-	}
-
-	if (info->is_elm_used && (mtd->writesize <= 4096)) {
-
-		if (hw_errors == BCH8_MAX_ERROR)
-			info->nand.ecc.bytes = BCH8_SIZE;
-		else
-			info->nand.ecc.bytes = BCH4_SIZE;
-
-		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;
-	} else {
-		/*
-		 * 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;
-		}
+	if (info->bch) {
+		free_bch(info->bch);
+		info->bch = NULL;
 	}
-
-	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
 
 /**
@@ -1806,11 +1741,6 @@ fail:
 }
 
 #else
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n");
-	return -1;
-}
 static int omap3_init_bch_tail(struct mtd_info *mtd)
 {
 	return -1;
@@ -1818,7 +1748,7 @@ static int omap3_init_bch_tail(struct mtd_info *mtd)
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
 static int omap_nand_probe(struct platform_device *pdev)
 {
@@ -1851,15 +1781,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
+	info->bch		= NULL;
+	info->of_node		= pdata->of_node;
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-	info->of_node		= pdata->of_node;
-#endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
@@ -2007,22 +1936,125 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
+	/* populate MTD interface based on ECC scheme */
+	switch (pdata->ecc_opt) {
+	case OMAP_ECC_HAM1_CODE_HW:
+		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
+		nand_chip->ecc.mode             = NAND_ECC_HW;
 		nand_chip->ecc.bytes            = 3;
 		nand_chip->ecc.size             = 512;
 		nand_chip->ecc.strength         = 1;
 		nand_chip->ecc.calculate        = omap_calculate_ecc;
 		nand_chip->ecc.hwctl            = omap_enable_hwecc;
 		nand_chip->ecc.correct          = omap_correct_data;
-		nand_chip->ecc.mode             = NAND_ECC_HW;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(mtd, pdata->ecc_opt);
-		if (err) {
+		break;
+
+	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 7;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH4_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 7 + 1;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			err = -ENODEV;
 			goto out_release_mem_region;
 		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 13;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
+			err = -EINVAL;
+			goto out_release_mem_region;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH8_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 13 + 1;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			goto out_release_mem_region;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	default:
+		pr_err("nand: error: invalid or unsupported ECC scheme\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* rom code layout */
@@ -2044,6 +2076,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 		nand_chip->ecc.layout = &omap_oobinfo;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
+		   (pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) ||
+		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
 		/* build OOB layout for BCH ECC correction */
 		err = omap3_init_bch_tail(mtd);
@@ -2076,6 +2110,7 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
+	omap3_free_bch(mtd);
 	kfree(info);
 
 	return err;
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:55 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:55 +0530
Subject: [PATCH v9 7/9] mtd: nand: omap: use drivers/mtd/nand/nand_bch.c
 wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-8-git-send-email-pekon@ti.com>

generic frame-work in mtd/nand/nand_bch.c is a wrapper above lib/bch.h which
encapsulates all control information specific to BCH ecc algorithm in software.
Thus this patch:
(1) replace omap specific implementations with equivalent wrapper in nand_bch.c
    so that more generic code is re-used. like;
        omap3_correct_data_bch() -> nand_bch_correct_data()
        omap3_free_bch() -> nand_bch_free()
(2) replace direct calls to lib/bch.c with wrapper functions defined in nand_bch.c
	init_bch() -> nand_bch_init()
(3) removes selection between BCH8 and BCH4 h/w ecc-schemes via KConfig.
    This selection is now based on ti,nand-ecc-opt and ti,elm-id DT bindings.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/Kconfig | 30 ++-------------
 drivers/mtd/nand/omap2.c | 96 +++++++++++-------------------------------------
 2 files changed, 26 insertions(+), 100 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..5836039 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
 
 config MTD_NAND_OMAP_BCH
 	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
-	tristate "Enable support for hardware BCH error correction"
+	tristate "Support hardware based BCH error correction"
 	default n
 	select BCH
-	select BCH_CONST_PARAMS
 	help
-	 Support for hardware BCH error correction.
-
-choice
-	prompt "BCH error correction capability"
-	depends on MTD_NAND_OMAP_BCH
-
-config MTD_NAND_OMAP_BCH8
-	bool "8 bits / 512 bytes (recommended)"
-	help
-	 Support correcting up to 8 bitflips per 512-byte block.
-	 This will use 13 bytes of spare area per 512 bytes of page data.
-	 This is the recommended mode, as 4-bit mode does not work
-	 on some OMAP3 revisions, due to a hardware bug.
-
-config MTD_NAND_OMAP_BCH4
-	bool "4 bits / 512 bytes"
-	help
-	 Support correcting up to 4 bitflips per 512-byte block.
-	 This will use 7 bytes of spare area per 512 bytes of page data.
-	 Note that this mode does not work on some OMAP3 revisions, due to a
-	 hardware bug. Please check your OMAP datasheet before selecting this
-	 mode.
-
-endchoice
+	  Some devices have built-in ELM hardware engine, which can be used to
+	  locate and correct errors when using BCH ECC scheme. This enables the
+	  driver support for same.
 
 if MTD_NAND_OMAP_BCH
 config BCH_CONST_M
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5f6e621..769ff65 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,7 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#include <linux/bch.h>
+#include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
@@ -140,7 +140,6 @@
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
 #define BADBLOCK_MARKER_LENGTH		2
-#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
@@ -173,7 +172,6 @@ struct omap_nand_info {
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
-	struct bch_control             *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1507,43 +1505,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_correct_data_bch - Decode received data and correct errors
- * @mtd: MTD device structure
- * @data: page data
- * @read_ecc: ecc read from nand flash
- * @calc_ecc: ecc read from HW ECC registers
- */
-static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
-				  u_char *read_ecc, u_char *calc_ecc)
-{
-	int i, count;
-	/* cannot correct more than 8 errors */
-	unsigned int errloc[8];
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-
-	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
-			   errloc);
-	if (count > 0) {
-		/* correct errors */
-		for (i = 0; i < count; i++) {
-			/* correct data only, not ecc bytes */
-			if (errloc[i] < 8*512)
-				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
-			pr_debug("corrected bitflip %u\n", errloc[i]);
-		}
-	} else if (count < 0) {
-		pr_err("ecc unrecoverable error\n");
-	}
-	return count;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1660,28 +1622,6 @@ static int is_elm_present(struct omap_nand_info *info,
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
- */
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-#else
-
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
@@ -1714,13 +1654,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-	info->bch		= NULL;
 	info->of_node		= pdata->of_node;
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
+	nand_chip->ecc.priv	= NULL;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1910,7 +1850,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		info->nand.ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1920,10 +1860,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		info->nand.ecc.priv		= nand_bch_init(mtd,
+							info->nand.ecc.size,
+							info->nand.ecc.bytes,
+							&info->nand.ecc.layout);
+		if (!info->nand.ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 		}
@@ -1975,7 +1916,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		info->nand.ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1985,10 +1926,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		info->nand.ecc.priv		= nand_bch_init(mtd,
+							info->nand.ecc.size,
+							info->nand.ecc.bytes,
+							&info->nand.ecc.layout);
+		if (!info->nand.ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2074,7 +2016,10 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
-	omap3_free_bch(mtd);
+	if (info->nand.ecc.priv) {
+		nand_bch_free(info->nand.ecc.priv);
+		info->nand.ecc.priv = NULL;
+	}
 	kfree(info);
 
 	return err;
@@ -2086,7 +2031,10 @@ static int omap_nand_remove(struct platform_device *pdev)
 	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(mtd);
+	if (info->nand.ecc.priv) {
+		nand_bch_free(info->nand.ecc.priv);
+		info->nand.ecc.priv = NULL;
+	}
 
 	if (info->dma)
 		dma_release_channel(info->dma);
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:54 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:54 +0530
Subject: [PATCH v9 6/9] mtd: nand: omap: clean-up ecc layout for BCH ecc
 schemes
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-7-git-send-email-pekon@ti.com>

In current implementation omap3_init_bch_tail() is a common function to
define ecc layout for different BCHx ecc schemes.This patch:
(1) removes omap3_init_bch_tail() and defines ecc layout for individual
    ecc-schemes along with populating their nand_chip->ecc data in
    omap_nand_probe(). This improves the readability and scalability of
    code for add new ecc schemes in future.
(2) removes 'struct nand_bbt_descr bb_descrip_flashbased' because default
    nand_bbt_descr in nand_bbt.c matches the same (.len=1 for x8 devices).
(3) add the check to see if NAND device has enough OOB/Spare bytes to
    store ECC signature of whole page, as defined by ecc-scheme.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 162 ++++++++++++++++++-----------------------------
 1 file changed, 63 insertions(+), 99 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 09ce85c..5f6e621 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -139,6 +139,7 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define BADBLOCK_MARKER_LENGTH		2
 #define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
@@ -149,17 +150,6 @@ static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
 
 /* 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
- * while scanning a device for factory marked good / bad blocks
- */
-static uint8_t scan_ff_pattern[] = { 0xff };
-static struct nand_bbt_descr bb_descrip_flashbased = {
-	.options = NAND_BBT_SCANALLPAGES,
-	.offs = 0,
-	.len = 1,
-	.pattern = scan_ff_pattern,
-};
-
 
 struct omap_nand_info {
 	struct nand_hw_control		controller;
@@ -184,7 +174,6 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct bch_control             *bch;
-	struct nand_ecclayout           ecclayout;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1686,65 +1675,8 @@ static void omap3_free_bch(struct mtd_info *mtd)
 	}
 }
 
-/**
- * omap3_init_bch_tail - Build an oob layout for BCH ECC correction.
- * @mtd: MTD device structure
- */
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	int i, steps, offset;
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	struct nand_ecclayout *layout = &info->ecclayout;
-
-	/* build oob layout */
-	steps = mtd->writesize/info->nand.ecc.size;
-	layout->eccbytes = steps*info->nand.ecc.bytes;
-
-	/* do not bother creating special oob layouts for small page devices */
-	if (mtd->oobsize < 64) {
-		pr_err("BCH ecc is not supported on small page devices\n");
-		goto fail;
-	}
-
-	/* reserve 2 bytes for bad block marker */
-	if (layout->eccbytes+2 > mtd->oobsize) {
-		pr_err("no oob layout available for oobsize %d eccbytes %u\n",
-		       mtd->oobsize, layout->eccbytes);
-		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] = 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].length = mtd->oobsize-2-layout->eccbytes;
-	info->nand.ecc.layout = layout;
-
-	if (!(info->nand.options & NAND_BUSWIDTH_16))
-		info->nand.badblock_pattern = &bb_descrip_flashbased;
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
-}
-
 #else
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	return -1;
-}
+
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
@@ -1756,8 +1688,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 	struct omap_nand_platform_data	*pdata;
 	struct mtd_info			*mtd;
 	struct nand_chip		*nand_chip;
+	struct nand_ecclayout		*ecclayout;
 	int				err;
-	int				i, offset;
+	int				i;
 	dma_cap_mask_t			mask;
 	unsigned			sig;
 	struct resource			*res;
@@ -1847,6 +1780,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
+	/* check for small page devices */
+	if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
+		pr_err("small page devices are not supported\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
+	/* populate read & write API based on xfer_type selected */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		nand_chip->read_buf   = omap_read_buf_pref;
@@ -1937,6 +1878,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* populate MTD interface based on ECC scheme */
+	nand_chip->ecc.layout	= &omap_oobinfo;
+	ecclayout		= &omap_oobinfo;
 	switch (pdata->ecc_opt) {
 	case OMAP_ECC_HAM1_CODE_HW:
 		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
@@ -1947,6 +1890,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.calculate        = omap_calculate_ecc;
 		nand_chip->ecc.hwctl            = omap_enable_hwecc;
 		nand_chip->ecc.correct          = omap_correct_data;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		if (nand_chip->options & NAND_BUSWIDTH_16)
+			ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
+		else
+			ecclayout->eccpos[0]	= 1;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		break;
 
 	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
@@ -1959,6 +1912,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap3_correct_data_bch;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
 		info->bch = init_bch(nand_chip->ecc.bytes,
 					nand_chip->ecc.strength,
@@ -1987,6 +1947,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
@@ -2010,6 +1977,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap3_correct_data_bch;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
 		info->bch = init_bch(nand_chip->ecc.bytes,
 					nand_chip->ecc.strength,
@@ -2044,6 +2018,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 			pr_err("nand: error: could not initialize ELM\n");
 			goto out_release_mem_region;
 		}
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
@@ -2057,34 +2038,17 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-
-		if (nand_chip->options & NAND_BUSWIDTH_16) {
-			offset = 2;
-		} else {
-			offset = 1;
-			nand_chip->badblock_pattern = &bb_descrip_flashbased;
-		}
-		omap_oobinfo.eccbytes = 3 * (mtd->writesize / 512);
-		for (i = 0; i < omap_oobinfo.eccbytes; i++)
-			omap_oobinfo.eccpos[i] = i+offset;
-
-		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = mtd->oobsize -
-					(offset + omap_oobinfo.eccbytes);
-
-		nand_chip->ecc.layout = &omap_oobinfo;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(mtd);
-		if (err) {
-			err = -EINVAL;
-			goto out_release_mem_region;
-		}
+	/* populate remaining ECC layout data */
+	ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH +
+							ecclayout->eccbytes);
+	for (i = 1; i < ecclayout->eccbytes; i++)
+		ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
+	/* check if NAND device's OOB is enough to store ECC signatures */
+	if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
+		pr_err("not enough OOB bytes required = %d, available=%d\n",
+					   ecclayout->eccbytes, mtd->oobsize);
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* second phase scan */
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:56 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:56 +0530
Subject: [PATCH v9 8/9] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-9-git-send-email-pekon@ti.com>

Updated DTS to replace deprecated binding with newer values
Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/boot/dts/am335x-evm.dts   | 3 +--
 arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e8ec875..1aee6ac 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -269,7 +269,6 @@
 				reg = <0 0 0>; /* CS0, offset 0 */
 				nand-bus-width = <8>;
 				ti,nand-ecc-opt = "bch8";
-				gpmc,device-nand = "true";
 				gpmc,device-width = <1>;
 				gpmc,sync-clk-ps = <0>;
 				gpmc,cs-on-ns = <0>;
@@ -296,7 +295,7 @@
 
 				#address-cells = <1>;
 				#size-cells = <1>;
-				elm_id = <&elm>;
+				ti,elm-id = <&elm>;
 
 				/* MTD partition table */
 				partition at 0 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index e2249bc..501f863 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -105,7 +105,7 @@
 		reg = <1 0 0x08000000>;
 		nand-bus-width = <8>;
 
-		ti,nand-ecc-opt = "sw";
+		ti,nand-ecc-opt = "ham1";
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <36>;
 		gpmc,cs-wr-off-ns = <36>;
-- 
1.8.1



From pekon at ti.com  Tue Oct 15 01:49:57 2013
From: pekon at ti.com (Pekon Gupta)
Date: Tue, 15 Oct 2013 11:19:57 +0530
Subject: [PATCH v9 9/9] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <1381816197-20477-10-git-send-email-pekon@ti.com>

"Managed Device Resource" or devm_xx calls takes care of automatic freeing
of the resource in case of:
- failure during driver probe
- failure during resource allocation
- detaching or unloading of driver module (rmmod)
Reference: Documentation/driver-model/devres.txt

Though OMAP NAND driver handles freeing of resource allocation in most of
the cases, but using devm_xx provides more clean and effortless approach
to handle all such cases.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 44 ++++++++++++++------------------------------
 1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 769ff65..0ed0d6f 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1642,7 +1642,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
+				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -1667,19 +1668,20 @@ static int omap_nand_probe(struct platform_device *pdev)
 	if (res == NULL) {
 		err = -EINVAL;
 		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto out_free_info;
+		goto out_release_mem_region;
 	}
 
 	info->phys_base = res->start;
 	info->mem_size = resource_size(res);
 
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
+	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
+				info->mem_size,	pdev->dev.driver->name)) {
 		err = -EBUSY;
-		goto out_free_info;
+		goto out_release_mem_region;
 	}
 
-	nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	nand_chip->IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
+						info->mem_size);
 	if (!nand_chip->IO_ADDR_R) {
 		err = -ENOMEM;
 		goto out_release_mem_region;
@@ -1781,8 +1783,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 			err = -ENODEV;
 			goto out_release_mem_region;
 		}
-		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-fifo", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-fifo", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_fifo, err);
@@ -1796,8 +1799,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 			err = -ENODEV;
 			goto out_release_mem_region;
 		}
-		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-count", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-count", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_count, err);
@@ -2010,45 +2014,25 @@ static int omap_nand_probe(struct platform_device *pdev)
 out_release_mem_region:
 	if (info->dma)
 		dma_release_channel(info->dma);
-	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
-	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
-out_free_info:
 	if (info->nand.ecc.priv) {
 		nand_bch_free(info->nand.ecc.priv);
 		info->nand.ecc.priv = NULL;
 	}
-	kfree(info);
-
 	return err;
 }
 
 static int omap_nand_remove(struct platform_device *pdev)
 {
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
-	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
 	if (info->nand.ecc.priv) {
 		nand_bch_free(info->nand.ecc.priv);
 		info->nand.ecc.priv = NULL;
 	}
-
 	if (info->dma)
 		dma_release_channel(info->dma);
-
-	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
-	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-
-	/* Release NAND device, its internal structures and partitions */
 	nand_release(mtd);
-	iounmap(nand_chip->IO_ADDR_R);
-	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
 	return 0;
 }
 
-- 
1.8.1



From sourav.poddar at ti.com  Tue Oct 15 02:06:47 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 15 Oct 2013 11:36:47 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131011100839.GA21581@sirena.org.uk>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
Message-ID: <525CDB77.4040201@ti.com>

Hi Mark,
On Friday 11 October 2013 03:38 PM, Mark Brown wrote:
> On Thu, Oct 10, 2013 at 04:38:19PM +0530, Sourav Poddar wrote:
>> On Thursday 10 October 2013 03:44 PM, Mark Brown wrote:
>>> Essentially what it looks like this hardware is trying to do is adapt a
>>> serial flash so it looks more like a parallel flash.  It's not clear
>>> that this is a good idea if we are already able to understand serial
>>> flash though.
>> Do you have any idea of how to go about implementing it in a more
>> cleaner way?(taking care of all what the spi controller hardware needs to
>> do for the memory mapped mode.). I understand doing a memcpy in the caller
>> itself, but how to tackle the spi controller configuration at that
>> point of time.
> You'd need to lock the bus and return the address for the caller to use
> until it released the lock.  Like I say I'd want to see numbers on this
> helping though.
>
I explored the whole scenario at hand and tried to create something 
based on previous
feedbacks that memcpy should be done only at the flash layer and the entire
spi framework should be bypassed.

But there is one problem which I faced while trying to achieve the 
above. Currently, spi
framework takes care of the runtime clock control part in 
pump_message(spi.c). So, at the
beginning of each transfer, there is a "get_sync" while at the end there 
is a "put_sync". Now, if
I try to do a memcpy in flash and bypass the SPI framework, there is a 
data abort as the SPI
controller clocks are cut.

>> Memory mapped is  a spi controller feature rather than a flash.
> The way it appears to be implemented is pretty flash specific isn't it?



From minal.shah at ti.com  Tue Oct 15 04:32:23 2013
From: minal.shah at ti.com (Shah, Minal)
Date: Tue, 15 Oct 2013 08:32:23 +0000
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
In-Reply-To: <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
References: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
 <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
Message-ID: <566CE8F1DB913147957287757DA6396B3E9D6A93@DBDE04.ent.ti.com>

Hi Brian,
Thanks a lot for the explanation; I understood the reason for failure.

> So why do you want to erase bad blocks?
The reason why I want to erase bad blocks is because they actually don't seem to be bad. 
Block0 itself is shown as bad.
I have few partitions (like MLO and u-boot env) of size equal to 1 erase block. The block is marked as bad and hence I cannot write anything to this partition. 
One of the solutions is to increase that partition size to 2 blocks so even if 1 block is bad then it will atleast be able to write to the other block of the same partition. But I don't think I should do this while the block is not really bad (what if all the blocks for some reason are marked as bad while they are actually not).

This question came in my mind from the fact that "nand scrub" command is allowed from u-boot which allows to also completely erase all the bad blocks; so why not from the kernel level.

Regards,
Minal

-----Original Message-----
From: Brian Norris [mailto:computersforpeace at gmail.com] 
Sent: Saturday, October 12, 2013 3:55 AM
To: Shah, Minal
Cc: Mike Frysinger; Mukherjee, Somnath; linux-mtd at lists.infradead.org; Gupta, Pekon; Parikh, Urmil
Subject: Re: MTD utils v1.5.0: MEMERASE64 ioctl failed error

Hi Minal,

On Wed, Oct 09, 2013 at 05:05:11AM +0000, Shah, Minal wrote:
> I am using MTD utils version 1.5.0 for DRA7 (Vayu) platform.
> 
> I have bad blocks in some of my NAND partitions which I am not able to erase from linux kernel.

MTD does not allow erasing bad blocks. This is prohibited by NAND
datasheets. There are occasions where, for debugging purposes, one might
need to erase a "bad" block that is not actually bad, but MTD does not
provide an interface for doing this. An interface for doing so was
discussed a while back, but nothing was merged.

> Using "-N" option in flash_eraseall ideally should have allowed erasing the bad block but I land up in "MEMERASE64 ioctl failed" error. 

"-N" just means that the user-space tool (flash_erase) won't try to skip
bad blocks. But that doesn't circumvent the in-kernel protection that
prevents the erase from succeeding. So the "Input/output" error you see
is completely expected and currently unavoidable, unless you modify your
kernel to remove this protection.

[snip]

So why do you want to erase bad blocks?

Brian


From broonie at kernel.org  Tue Oct 15 07:16:47 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 12:16:47 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <525CDB77.4040201@ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com>
Message-ID: <20131015111647.GX2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 11:36:47AM +0530, Sourav Poddar wrote:

> But there is one problem which I faced while trying to achieve the
> above. Currently, spi
> framework takes care of the runtime clock control part in
> pump_message(spi.c). So, at the
> beginning of each transfer, there is a "get_sync" while at the end
> there is a "put_sync". Now, if
> I try to do a memcpy in flash and bypass the SPI framework, there is
> a data abort as the SPI
> controller clocks are cut.

Can you fix this by enabling the clock is enabled when you return the
buffer to the MTD layer and then disabling the clock when the buffer is
released?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/ba2b2f4a/attachment.sig>

From sourav.poddar at ti.com  Tue Oct 15 07:49:07 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 15 Oct 2013 17:19:07 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131015111647.GX2443@sirena.org.uk>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
Message-ID: <525D2BB3.4020705@ti.com>

Hi Mark,
On Tuesday 15 October 2013 04:46 PM, Mark Brown wrote:
> On Tue, Oct 15, 2013 at 11:36:47AM +0530, Sourav Poddar wrote:
>
>> But there is one problem which I faced while trying to achieve the
>> above. Currently, spi
>> framework takes care of the runtime clock control part in
>> pump_message(spi.c). So, at the
>> beginning of each transfer, there is a "get_sync" while at the end
>> there is a "put_sync". Now, if
>> I try to do a memcpy in flash and bypass the SPI framework, there is
>> a data abort as the SPI
>> controller clocks are cut.
> Can you fix this by enabling the clock is enabled when you return the
> buffer to the MTD layer and then disabling the clock when the buffer is
> released?
Sorry, I did not get you here. With memory mapped read, there is no
buffer exchanged, everything takes place at the mtd layer only, what gets
exchanged is just the memory mapped address.

Here is the patch which I did on top of the subject patch series, wherein my
controller is in default memory mapped mode, while doing a read in mtd layer
its just does a memcopy and return.

This gives me a data abort as pm_runtime_get_sync is not called on the 
qspi controller.


Index: linux/drivers/mtd/devices/m25p80.c
===================================================================
--- linux.orig/drivers/mtd/devices/m25p80.c    2013-10-15 
17:08:15.000000000 +0530
+++ linux/drivers/mtd/devices/m25p80.c    2013-10-15 17:08:26.000000000 
+0530
@@ -102,7 +102,7 @@
      u8            *command;
      bool            fast_read;
      bool            quad_read;
-    bool            mmap_read;
+    void            *mmap_read;
  };

  static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -438,18 +438,21 @@
      pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
              __func__, (u32)from, len);
      printk("enter mtd quad..\n");
+
+    if (flash->mmap_read) {
+        printk("memory map=%x\n", flash->mmap_read);
+        memcpy(buf, flash->mmap_read + from, len);
+        *retlen = len;
+        return 0;
+    }
+
      spi_message_init(&m);
      memset(t, 0, (sizeof(t)));

-    if (flash->mmap_read)
-        t[0].memory_map = 1;
      t[0].tx_buf = flash->command;
-    t[0].len = flash->mmap_read ? from : (m25p_cmdsz(flash) + 
(flash->quad_read ? 1 : 0));
-    printk("t[0].len=%d\n", t[0].len);
+    t[0].len = (m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0));
      spi_message_add_tail(&t[0], &m);

-        if (flash->mmap_read)
-        t[1].memory_map = 1;
      t[1].rx_buf = buf;
      t[1].len = len;
      t[1].rx_nbits = SPI_NBITS_QUAD;
@@ -476,7 +479,7 @@

      spi_sync(flash->spi, &m);

-    *retlen = flash->mmap_read ? len : (m.actual_length - 
m25p_cmdsz(flash) -
+    *retlen = (m.actual_length - m25p_cmdsz(flash) -
              (flash->quad_read ? 1 : 0));

      mutex_unlock(&flash->lock);
@@ -1215,7 +1218,7 @@

      if (spi->mode && SPI_RX_MMAP) {
          printk("memory mapped mode set\n");
-        flash->mmap_read = true;
+        flash->mmap_read = spi->memory_map;
      }
      flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
                  (flash->quad_read ? 1 : 0)), GFP_KERNEL);
Index: linux/drivers/spi/spi-ti-qspi.c
===================================================================
--- linux.orig/drivers/spi/spi-ti-qspi.c    2013-10-15 
17:08:15.000000000 +0530
+++ linux/drivers/spi/spi-ti-qspi.c    2013-10-15 17:15:52.000000000 +0530
@@ -256,6 +256,8 @@
              break;
          }
          ti_qspi_write(qspi, memval, QSPI_SPI_SETUP0_REG);
+        enable_qspi_memory_mapped(qspi);
+        spi->memory_map = qspi->mmap_base;
          spi->mode |= SPI_RX_MMAP;
      }

@@ -433,22 +435,13 @@
      qspi->cmd |= QSPI_FLEN(frame_length);
      qspi->cmd |= QSPI_WC_CMD_INT_EN;

+    disable_qspi_memory_mapped(qspi);
+
      ti_qspi_write(qspi, QSPI_WC_INT_EN, QSPI_INTR_ENABLE_SET_REG);

      mutex_lock(&qspi->list_lock);

      list_for_each_entry(t, &m->transfers, transfer_list) {
-               if (t->memory_map) {
-                       if (t->tx_buf) {
-                               from = t->len;
-                               continue;
-                       }
-                       enable_qspi_memory_mapped(qspi);
-                       memcpy(t->rx_buf, qspi->mmap_base + from, t->len);
-                       disable_qspi_memory_mapped(qspi);
-                       goto out;
-               }
-
          qspi->cmd |= QSPI_WLEN(t->bits_per_word);

          ret = qspi_transfer_msg(qspi, t);
@@ -461,13 +454,13 @@
          m->actual_length += t->len;
      }

-out:
      mutex_unlock(&qspi->list_lock);

      m->status = status;
      spi_finalize_current_message(master);

      ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);
+    enable_qspi_memory_mapped(qspi);

      return status;
  }
@@ -599,6 +592,7 @@
      if (res_mmap) {
          printk("mmap_available\n");
          qspi->mmap_base = devm_ioremap_resource(&pdev->dev, res_mmap);
+        printk("qspi->mmap_base=%x\n", qspi->mmap_base);
          if (IS_ERR(qspi->mmap_base)) {
              ret = PTR_ERR(qspi->mmap_base);
              goto free_master;
Index: linux/include/linux/spi/spi.h
===================================================================
--- linux.orig/include/linux/spi/spi.h    2013-10-15 17:08:15.000000000 
+0530
+++ linux/include/linux/spi/spi.h    2013-10-15 17:08:26.000000000 +0530
@@ -94,6 +94,7 @@
  #define SPI_RX_MMAP    0x1000            /* Memory mapped read */
      u8            bits_per_word;
      int            irq;
+     void __iomem        *memory_map;
      void            *controller_state;
      void            *controller_data;
      char            modalias[SPI_NAME_SIZE];
@@ -556,7 +557,6 @@
      u16        delay_usecs;
      u32        speed_hz;

-    bool    memory_map;
      struct list_head transfer_list;
  };




From broonie at kernel.org  Tue Oct 15 08:46:56 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 13:46:56 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <525D2BB3.4020705@ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com>
Message-ID: <20131015124656.GM2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 05:19:07PM +0530, Sourav Poddar wrote:
> On Tuesday 15 October 2013 04:46 PM, Mark Brown wrote:

> >Can you fix this by enabling the clock is enabled when you return the
> >buffer to the MTD layer and then disabling the clock when the buffer is
> >released?

> Sorry, I did not get you here. With memory mapped read, there is no
> buffer exchanged, everything takes place at the mtd layer only, what gets
> exchanged is just the memory mapped address.

The buffer is the memory mapped address - part of getting the address
should be preparing the hardware for it.

>      if (spi->mode && SPI_RX_MMAP) {
>          printk("memory mapped mode set\n");
> -        flash->mmap_read = true;
> +        flash->mmap_read = spi->memory_map;

So this probably needs to be a function call to get the buffer (and a
corresponding one to free it).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/14d79936/attachment.sig>

From sourav.poddar at ti.com  Tue Oct 15 09:23:46 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 15 Oct 2013 18:53:46 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131015124656.GM2443@sirena.org.uk>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
Message-ID: <525D41E2.30206@ti.com>

On Tuesday 15 October 2013 06:16 PM, Mark Brown wrote:
> On Tue, Oct 15, 2013 at 05:19:07PM +0530, Sourav Poddar wrote:
>> On Tuesday 15 October 2013 04:46 PM, Mark Brown wrote:
>>> Can you fix this by enabling the clock is enabled when you return the
>>> buffer to the MTD layer and then disabling the clock when the buffer is
>>> released?
>> Sorry, I did not get you here. With memory mapped read, there is no
>> buffer exchanged, everything takes place at the mtd layer only, what gets
>> exchanged is just the memory mapped address.
> The buffer is the memory mapped address - part of getting the address
> should be preparing the hardware for it.
>
>>       if (spi->mode&&  SPI_RX_MMAP) {
>>           printk("memory mapped mode set\n");
>> -        flash->mmap_read = true;
>> +        flash->mmap_read = spi->memory_map;
> So this probably needs to be a function call to get the buffer (and a
> corresponding one to free it).
So, the flow can be something like this:

drivers/mtd/devices/m25p80.c
get_flash_buf()
{
     lock();

      t[0] = GET_BUFFER;
      t[1] = buf;
      ......

      spi_sync();

     unlock();
}

mtd_read
{
     get_flash_buf();

     if (flash->buf) {
         memcpy();
        return 0;
   }
}

Not sure, if free buf is needed as devm_* variant is used to allocate that
memory.


}



From marex at denx.de  Tue Oct 15 09:44:11 2013
From: marex at denx.de (Marek Vasut)
Date: Tue, 15 Oct 2013 15:44:11 +0200
Subject: [PATCH][v2] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <1381815545-4518-1-git-send-email-Priyanka.Jain@freescale.com>
References: <1381815545-4518-1-git-send-email-Priyanka.Jain@freescale.com>
Message-ID: <201310151544.11481.marex@denx.de>

Dear Priyanka Jain,

> Micron N25Q512A is a spi flash memory with following features:
> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
> -Memory is organised as 1024(64KB) main sectors.
> -Each sector is divided into 256 pages.
> -Register set/Opcodes are similar to other N25Q family products.
> 
> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>

Feel free to add my

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

Thanks!

> ---
>  Changes for v2:
> 	Corrected number of sectors to 1024 based on
> 	inputs from Marek Vasut and Brian Norris
> 
>  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 26b14f9..94e3b53 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -774,6 +774,7 @@ static const struct spi_device_id m25p_ids[] = {
>  	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
>  	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
>  	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
> +	{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
> 
>  	/* PMC */
>  	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },

Best regards,
Marek Vasut


From mikedunn at newsguy.com  Tue Oct 15 10:17:43 2013
From: mikedunn at newsguy.com (Mike Dunn)
Date: Tue, 15 Oct 2013 07:17:43 -0700
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
In-Reply-To: <566CE8F1DB913147957287757DA6396B3E9D6A93@DBDE04.ent.ti.com>
References: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
 <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
 <566CE8F1DB913147957287757DA6396B3E9D6A93@DBDE04.ent.ti.com>
Message-ID: <525D4E87.7010908@newsguy.com>

On 10/15/2013 01:32 AM, Shah, Minal wrote:
> Hi Brian,
> Thanks a lot for the explanation; I understood the reason for failure.
> 
>> So why do you want to erase bad blocks?
> The reason why I want to erase bad blocks is because they actually don't seem to be bad. 
> Block0 itself is shown as bad.
> I have few partitions (like MLO and u-boot env) of size equal to 1 erase block. The block is marked as bad and hence I cannot write anything to this partition. 
> One of the solutions is to increase that partition size to 2 blocks so even if 1 block is bad then it will atleast be able to write to the other block of the same partition. But I don't think I should do this while the block is not really bad (what if all the blocks for some reason are marked as bad while they are actually not).
> 
> This question came in my mind from the fact that "nand scrub" command is allowed from u-boot which allows to also completely erase all the bad blocks; so why not from the kernel level.
> 
> Regards,
> Minal
> 
> -----Original Message-----
> From: Brian Norris [mailto:computersforpeace at gmail.com] 
> Sent: Saturday, October 12, 2013 3:55 AM
> To: Shah, Minal
> Cc: Mike Frysinger; Mukherjee, Somnath; linux-mtd at lists.infradead.org; Gupta, Pekon; Parikh, Urmil
> Subject: Re: MTD utils v1.5.0: MEMERASE64 ioctl failed error
> 
> Hi Minal,
> 
> On Wed, Oct 09, 2013 at 05:05:11AM +0000, Shah, Minal wrote:
>> I am using MTD utils version 1.5.0 for DRA7 (Vayu) platform.
>>
>> I have bad blocks in some of my NAND partitions which I am not able to erase from linux kernel.
> 
> MTD does not allow erasing bad blocks. This is prohibited by NAND
> datasheets. There are occasions where, for debugging purposes, one might
> need to erase a "bad" block that is not actually bad, but MTD does not
> provide an interface for doing this. An interface for doing so was
> discussed a while back, but nothing was merged.


Yes, this is a shortcoming in mtd, I think.  Blocks can be marked as bad, but
never "un-marked".  This is the reason I needed a module parameter
"ignore_badblocks" in the docg4 driver.

But any solution is complicated by the diversity of methods for marking bad
blocks (fixed or relocatable flash table, oob marker), and various reasons why
it is so marked (factory, user).  This is why u-boot says that 'nand scrub' is
potentially "unsafe".  You have to know the internals of your device.

Mike



From pekon at ti.com  Tue Oct 15 11:33:19 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Tue, 15 Oct 2013 15:33:19 +0000
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <525D41E2.30206@ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA23446@DBDE04.ent.ti.com>



> From:  Poddar, Sourav
> > On Tuesday 15 October 2013 06:16 PM, Mark Brown wrote:
> > On Tue, Oct 15, 2013 at 05:19:07PM +0530, Sourav Poddar wrote:
> >> On Tuesday 15 October 2013 04:46 PM, Mark Brown wrote:
> >>> Can you fix this by enabling the clock is enabled when you return the
> >>> buffer to the MTD layer and then disabling the clock when the buffer is
> >>> released?
> >> Sorry, I did not get you here. With memory mapped read, there is no
> >> buffer exchanged, everything takes place at the mtd layer only, what gets
> >> exchanged is just the memory mapped address.
> > The buffer is the memory mapped address - part of getting the address
> > should be preparing the hardware for it.
> >
> >>       if (spi->mode&&  SPI_RX_MMAP) {
> >>           printk("memory mapped mode set\n");
> >> -        flash->mmap_read = true;
> >> +        flash->mmap_read = spi->memory_map;
> > So this probably needs to be a function call to get the buffer (and a
> > corresponding one to free it).
> So, the flow can be something like this:
> 
> drivers/mtd/devices/m25p80.c
> get_flash_buf()
> {
>      lock();
> 
>       t[0] = GET_BUFFER;
>       t[1] = buf;
>       ......
> 
>       spi_sync();
> 
>      unlock();
> }
> 
Problem here..
spi_sync() is not blocking, that means it would just add a spi_message
to queue and return. And it depends on kthread_worker when it pumps
this spi_message to QPSI controller driver for actual configuration.
So this is actually a race-condition. You cannot use spi_sync() to configure.

(refer my comments in previous emails).
If you really want to configure QSPI controller just before memcpy(),
Then you need to somehow prevent spi kthead_worker from accessing.
This you can do by locking the spi_meesage queue/list at that time.


> mtd_read
> {
>      get_flash_buf();
> 
>      if (flash->buf) {
>          memcpy();
>         return 0;
>    }
> }
> 
> Not sure, if free buf is needed as devm_* variant is used to allocate that
> memory.
> 
> 
> }

With regards, pekon


From broonie at kernel.org  Tue Oct 15 11:53:39 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 16:53:39 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <525D41E2.30206@ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
Message-ID: <20131015155339.GR2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 06:53:46PM +0530, Sourav Poddar wrote:

> Not sure, if free buf is needed as devm_* variant is used to allocate that
> memory.

I would expect the buffer to only be requested by the flash driver when
actively in use.  This will enable the SPI controller driver to save
power (by stopping the clock for example as in your case) when the flash
isn't actively being used.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/3ce90666/attachment.sig>

From broonie at kernel.org  Tue Oct 15 12:01:01 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 17:01:01 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA23446@DBDE04.ent.ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23446@DBDE04.ent.ti.com>
Message-ID: <20131015160101.GS2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 03:33:19PM +0000, Gupta, Pekon wrote:

> Problem here..
> spi_sync() is not blocking, that means it would just add a spi_message
> to queue and return. And it depends on kthread_worker when it pumps
> this spi_message to QPSI controller driver for actual configuration.
> So this is actually a race-condition. You cannot use spi_sync() to configure.

No, spi_sync() is blocking - spi_async() is non-blocking.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/995f01f3/attachment.sig>

From vapier at gentoo.org  Tue Oct 15 12:26:48 2013
From: vapier at gentoo.org (Mike Frysinger)
Date: Tue, 15 Oct 2013 12:26:48 -0400
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
In-Reply-To: <566CE8F1DB913147957287757DA6396B3E9D6A93@DBDE04.ent.ti.com>
References: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
 <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
 <566CE8F1DB913147957287757DA6396B3E9D6A93@DBDE04.ent.ti.com>
Message-ID: <201310151226.51513.vapier@gentoo.org>

On Tuesday 15 October 2013 04:32:23 Shah, Minal wrote:
> Hi Brian,
> Thanks a lot for the explanation; I understood the reason for failure.
> 
> > So why do you want to erase bad blocks?
> 
> The reason why I want to erase bad blocks is because they actually don't
> seem to be bad. Block0 itself is shown as bad.
> I have few partitions (like MLO and u-boot env) of size equal to 1 erase
> block. The block is marked as bad and hence I cannot write anything to
> this partition. One of the solutions is to increase that partition size to
> 2 blocks so even if 1 block is bad then it will atleast be able to write
> to the other block of the same partition. But I don't think I should do
> this while the block is not really bad (what if all the blocks for some
> reason are marked as bad while they are actually not).
> 
> This question came in my mind from the fact that "nand scrub" command is
> allowed from u-boot which allows to also completely erase all the bad
> blocks; so why not from the kernel level.

as mentioned, there was discussion some time ago about adding this 
functionality.  but the work never finished.  if you're interested, i'd suggest 
picking up the work there.
-mike
-------------- 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/20131015/6332a49b/attachment.sig>

From pekon at ti.com  Tue Oct 15 12:54:34 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Tue, 15 Oct 2013 16:54:34 +0000
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131015160101.GS2443@sirena.org.uk>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23446@DBDE04.ent.ti.com>
 <20131015160101.GS2443@sirena.org.uk>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA234E2@DBDE04.ent.ti.com>

> From: Mark Brown [mailto:broonie at kernel.org]
> > On Tue, Oct 15, 2013 at 03:33:19PM +0000, Gupta, Pekon wrote:
> > Problem here..
> > spi_sync() is not blocking, that means it would just add a spi_message
> > to queue and return. And it depends on kthread_worker when it pumps
> > this spi_message to QPSI controller driver for actual configuration.
> > So this is actually a race-condition. You cannot use spi_sync() to configure.
> 
> No, spi_sync() is blocking - spi_async() is non-blocking.

Sorry my bad, I must have been dreaming or something.
Yes, it's spi_sync() is blocking, its clearly written in its comments too..

with regards, pekon


From computersforpeace at gmail.com  Tue Oct 15 13:07:47 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 10:07:47 -0700
Subject: [PATCH][v2] mtd: m25p80: Add support for Micron N25Q512A memory
In-Reply-To: <1381815545-4518-1-git-send-email-Priyanka.Jain@freescale.com>
References: <1381815545-4518-1-git-send-email-Priyanka.Jain@freescale.com>
Message-ID: <20131015170742.GR23337@ld-irv-0074.broadcom.com>

On Tue, Oct 15, 2013 at 11:09:05AM +0530, Priyanka Jain wrote:
> Micron N25Q512A is a spi flash memory with following features:
> -64MB size, 1.8V, Mulitple I/O, 4KB Sector erase memory.
> -Memory is organised as 1024(64KB) main sectors.
> -Each sector is divided into 256 pages.
> -Register set/Opcodes are similar to other N25Q family products.
> 
> Signed-off-by: Priyanka Jain <Priyanka.Jain at freescale.com>

Applied to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Tue Oct 15 13:16:07 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 10:16:07 -0700
Subject: [PATCH] mtd: Move major number definitions to major.h
In-Reply-To: <1381698323-18932-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1381698323-18932-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <CAN8TOE-SDnAX0onQoe0B971n5oaGppyjaaQ=g=ONY+x3han+3A@mail.gmail.com>

+ LKML

On Sun, Oct 13, 2013 at 2:05 PM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> This patch moves the char and block major number definitions
> to major.h to be with the rest of the major numbers.
> While doing this, include major.h in the files that need it.

The patch looks good to me. It touches a common file (major.h), but
it's a very low-noise file, so I don't imagine we'll get any
conflicts. Unless anyone complains, I'll take this into the MTD tree
(l2-mtd.git) soon.

> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

Thanks,
Brian

(Patch left for context)

>  drivers/mtd/devices/block2mtd.c | 1 +
>  drivers/mtd/mtdblock.c          | 1 +
>  drivers/mtd/mtdblock_ro.c       | 1 +
>  drivers/mtd/mtdchar.c           | 1 +
>  drivers/mtd/mtdcore.c           | 1 +
>  drivers/mtd/mtdsuper.c          | 1 +
>  drivers/mtd/ubi/build.c         | 1 +
>  include/linux/mtd/mtd.h         | 3 ---
>  include/uapi/linux/major.h      | 2 ++
>  9 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
> index 5cb4c04..d9fd87a 100644
> --- a/drivers/mtd/devices/block2mtd.c
> +++ b/drivers/mtd/devices/block2mtd.c
> @@ -20,6 +20,7 @@
>  #include <linux/mutex.h>
>  #include <linux/mount.h>
>  #include <linux/slab.h>
> +#include <linux/major.h>
>
>  /* Info for the block device */
>  struct block2mtd_dev {
> diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
> index 53884cc..485ea75 100644
> --- a/drivers/mtd/mtdblock.c
> +++ b/drivers/mtd/mtdblock.c
> @@ -32,6 +32,7 @@
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/blktrans.h>
>  #include <linux/mutex.h>
> +#include <linux/major.h>
>
>
>  struct mtdblk_dev {
> diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
> index 70d27b4..fb5dc89 100644
> --- a/drivers/mtd/mtdblock_ro.c
> +++ b/drivers/mtd/mtdblock_ro.c
> @@ -24,6 +24,7 @@
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/blktrans.h>
>  #include <linux/module.h>
> +#include <linux/major.h>
>
>  static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
>                               unsigned long block, char *buf)
> diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> index 684bfa3..9aa0c5e 100644
> --- a/drivers/mtd/mtdchar.c
> +++ b/drivers/mtd/mtdchar.c
> @@ -32,6 +32,7 @@
>  #include <linux/mount.h>
>  #include <linux/blkpg.h>
>  #include <linux/magic.h>
> +#include <linux/major.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
>  #include <linux/mtd/map.h>
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 92311a5..7189089 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -37,6 +37,7 @@
>  #include <linux/backing-dev.h>
>  #include <linux/gfp.h>
>  #include <linux/slab.h>
> +#include <linux/major.h>
>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
> diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
> index 334da5f..20c02a3 100644
> --- a/drivers/mtd/mtdsuper.c
> +++ b/drivers/mtd/mtdsuper.c
> @@ -17,6 +17,7 @@
>  #include <linux/export.h>
>  #include <linux/ctype.h>
>  #include <linux/slab.h>
> +#include <linux/major.h>
>
>  /*
>   * compare superblocks to see if they're equivalent
> diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
> index 315dcc6..e05dc62 100644
> --- a/drivers/mtd/ubi/build.c
> +++ b/drivers/mtd/ubi/build.c
> @@ -41,6 +41,7 @@
>  #include <linux/kthread.h>
>  #include <linux/kernel.h>
>  #include <linux/slab.h>
> +#include <linux/major.h>
>  #include "ubi.h"
>
>  /* Maximum length of the 'mtd=' parameter */
> diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
> index 88409b8..8cc0e2f 100644
> --- a/include/linux/mtd/mtd.h
> +++ b/include/linux/mtd/mtd.h
> @@ -29,9 +29,6 @@
>
>  #include <asm/div64.h>
>
> -#define MTD_CHAR_MAJOR 90
> -#define MTD_BLOCK_MAJOR 31
> -
>  #define MTD_ERASE_PENDING      0x01
>  #define MTD_ERASING            0x02
>  #define MTD_ERASE_SUSPEND      0x04
> diff --git a/include/uapi/linux/major.h b/include/uapi/linux/major.h
> index 6a8ca98..620252e 100644
> --- a/include/uapi/linux/major.h
> +++ b/include/uapi/linux/major.h
> @@ -54,6 +54,7 @@
>  #define ACSI_MAJOR             28
>  #define AZTECH_CDROM_MAJOR     29
>  #define FB_MAJOR               29   /* /dev/fb* framebuffers */
> +#define MTD_BLOCK_MAJOR                31
>  #define CM206_CDROM_MAJOR      32
>  #define IDE2_MAJOR             33
>  #define IDE3_MAJOR             34
> @@ -105,6 +106,7 @@
>  #define IDE6_MAJOR             88
>  #define IDE7_MAJOR             89
>  #define IDE8_MAJOR             90
> +#define MTD_CHAR_MAJOR         90
>  #define IDE9_MAJOR             91
>
>  #define DASD_MAJOR             94


From computersforpeace at gmail.com  Tue Oct 15 13:22:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 10:22:54 -0700
Subject: N25Q256A 13E40
In-Reply-To: <201310120317.12174.marex@denx.de>
References: <201310071824.01028.marex@denx.de>
 <201310091214.02740.marex@denx.de>
 <20131009214401.GD23337@ld-irv-0074.broadcom.com>
 <201310120317.12174.marex@denx.de>
Message-ID: <CAN8TOE8OO0_TpKJJU8ab1M=60zyZ9H7fhZBVw7AaM=pUAwOEuQ@mail.gmail.com>

Hi Marek,

On Fri, Oct 11, 2013 at 6:17 PM, Marek Vasut <marex at denx.de> wrote:

>> On Wed, Oct 09, 2013 at 12:14:02PM +0200, Marek Vasut wrote:
>> > > On Mon, Oct 7, 2013 at 9:24 AM, Marek Vasut <marex at denx.de> wrote:
>> > > > Let's talk about our favourite chip :) I just got my hands on
>> > > > N25Q256A . Since there was quite a flurry of patches for this and
>> > > > similar chips and I got it working on a different chip with exactly
>> > > > the same IDs and type, I'd would expect linux to work with this one
>> > > > too. Guess what ... ;-)
>> > > >
>> > > > This particular incarnation of N25Q256A completely ignores the 4-byte
>> > > > ERASE (0xdc) command. Apparently, if I look closely, it's N25Q256A
>> > > > 13E40 variant and seeing the Note #14 (datasheet page 30 / below
>> > > > Table 18. Command set), quoting:
>> > > >
>> > > > 14.This command is only for part numbers N25Q256A83ESF40x and
>> > > > N25Q256A83E1240x.
>> > >
>> > > This note also applies to PAGE_PROGRAM_4B (0x12) as well, right?
>> >
>> > Yeah, both ERASE_4B and PP_4B or whatever they're called there.
>> > Interestingly enough, READ_4B works ;-/
>>
>> Well, the READ_4B consistency is (unintentionally?) helpful for my
>> systems, as we have begun implementing a jumper switch so that the boot
>> ROM will know whether to use FAST_READ or FAST_READ_4B. Since
>> essentially all large SPI flash at *least* support the READ_4B command
>> (as you noted), we can reliably boot from the flash, no matter what mode
>> it is left in. After booting, we can choose the appropriate mode for
>> programming/erasing.
>
> I wish I had such a bootrom. In my case (freescale imx28), the bootrom can just
> do 3-byte operation and that's it. I believe the only way around here is to
> power-cycle the spi flash before the bootrom starts using it.

Well, such is life when dealing with these flash. Manufacturers
apparently didn't understand the impact that adding incompatible
mode-switches to such fundamental commands would have :(

>> > > [Now that I went back to look at some more code:] Wait, but we don't
>> > > even try to use the 4-byte dedicated commands like 0xdc on Micron
>> > > flash, so why are you having this problem? The code currently stands
>> >
>> > > as:
>> > The JEDEC_MFR for this flash Micron N25Q256A is CFI_MFR_ST (I wonder
>> > why).
>>
>> Probably some series of acquisitions?
>>
>> But you didn't quite answer my question. Are you having problems with
>> this Micron/ST/something-that's-not-AMD-or-Spansion flash using the
>> current mainline? Or did you only have trouble when you tried modifying
>> the code to use the dedicated 4-byte addressing commands?
>
> Urgh, I just noticed I did exactly this. I modified the driver to enable this 4-
> byte opcodes and then just forgot about it. Pardon my stupidity :(

No problem. The manufacturers haven't made this an easy problem.

Brian


From wd at denx.de  Tue Oct 15 13:40:31 2013
From: wd at denx.de (Wolfgang Denk)
Date: Tue, 15 Oct 2013 19:40:31 +0200
Subject: Grow UBI device?
In-Reply-To: <1381393038.7875.83.camel@sauron.fi.intel.com>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <1381393038.7875.83.camel@sauron.fi.intel.com>
Message-ID: <20131015174031.E52CF380420@gemini.denx.de>

Dear Artem,

In message <1381393038.7875.83.camel at sauron.fi.intel.com> you wrote:
> Wolfgang, people already answered you, and frankly I did not read all
> the answers :-) But here is my brief version.

Thanks.

> On Tue, 2013-10-08 at 21:28 +0200, Wolfgang Denk wrote:
> > I'm looking for a clever way to migrate devices (in the field) from
> > JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
> > device (which covers the whole NAND chip) with several volumes used
> > with UBIFS.  Unfortunately I must keep some of the existing data.
> 
> And I guess there is no temporary storage where you could copy JFFS2
> files, re-format the flash, and copy the files back.

Correct.

> > It would be nice if I could start with a UBI device that is smaller
> > than the NAND, so I can keep an existing MTD partition with a JFFS2
> > file system.
> 
> You mean that on the existing systems, you already have an extra MTD
> partition, or you somehow can create one.
> 
> Then you want to UBI/UBIFS-format the extra partition. Then copy
> required JFFS2 files there. And then kill JFFS2 partitions and "merge"
> them with the extra partition, and end up with UBI/UBIFS covering all
> the space.

Correct.

> > Is there a way to "grow" the existing UBI device so that it now also
> > covers the rest of the NAND chip?  Or is my only option to create a
> > second UBI device?
> 
> I think so, unless you use the fastmap feature. Suppose you don't.

We don't.  We may want to do this later, but certainly not during this
migration steps.

> 1. Format mtd2 with UBI. Just erasing should be OK, or you can use
> ubiformat: http://www.linux-mtd.infradead.org/faq/ubi.html#L_ubierase
> 
> Then you attach mtd2 (ubiattach) and you get an UBI device (/dev/ubiX).
> 
> 2. Create a volume on /dev/ubiX which spans entire UBI device
> (ubimkvol -t AFAIR). You end up with UBI volume /dev/ubiX_0.
> 
> 3. And here is important part - you format /dev/ubiX_0 with JFFS2 but
> correctly.

With JFFS2?  I would expect to see "UBIFS" here?

> UBIFS has this "automatic expand" feature. Which means that if the UBI
> volume underneath it becomes larger, UBIFS will expand automatically and
> take the entire (larger) UBI volume.
> 
> However, there is a _limit_ to how much UBIFS can expand from the
> original size. And you want to watch this limit and make it big enough.
> 
> The limit is connected with the "-c" option of mkfs.ubifs. Please, check
> the docs - they explain what exactly -c controls and how it is related
> to the maximum UBIFS file-system size:
> 
> http://www.linux-mtd.infradead.org/faq/ubifs.html#L_max_leb_cnt
> 
> So, select proper -c.

Thanks for the poointer.  I would have missed this.

> If you do not use mkfs.ubifs, but just attach /dev/ubiX_0, the UBIFS
> kernel driver will format the volume automatically. It will select the
> -c value itself. Since this value is power of 2, it will just take the
> smallest power-of-2 value. It may be OK for your purposes, may be not.
> It is safer to use mkfs.ubifs with explicit -c.

Agreed.  It would have worked in our case, as mtd1 is 32 MB and mtd2
is 96 MB on a 128 MB NAND device, but it's much better to have full
control.

> 4. Copy important files from JFFS2-mtd1 to UBIFS-UBI-mtd2.
> 
> 5. Erase mtd1 (or you can do this later too)
> 
> 6. I do not know how you do this, but kill mtd1, and resize mtd2.
> Probably mtd2 will then be named mtd1 after reboot. If you always refer
> your MTD partitions and UBI volumes by name, you should not suffer to
> much from mtd2 becoming mtd1.

The plan is to just have another mtd3 which covers the whole device.
So I would detach UBI from mtd2 and re-attach to mtd3.

> Lets suppose there is no rename, for simplicity.
> 
> 7. Make sure former JFFS2-mtd1 eraseblocks are erased (unless you did
> this at step 5).
> 
> 8. Attach mtd2 to UBI. UBI will automatically "take" the new
> eraseblocks, erase them and write UBI headers there, and make available.
> 
> 9. Volume size will still be the same, and you need to re-size it using
> ubiresize.
> 
> 10. Mount the resized volume. UBI will enlarge itself.

That's just amazing :-)

> Problem solved.
> 
> Surely you do not want power cuts during this operations. If you need to
> survive power cuts, I guess it is possible, but more complex.

Thanks a lot for all the help, it's highly appreciated!

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"At least they're __________EXPERIENCED incompetents"


From computersforpeace at gmail.com  Tue Oct 15 14:01:42 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 11:01:42 -0700
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <525D41E2.30206@ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
Message-ID: <20131015180142.GS23337@ld-irv-0074.broadcom.com>

Hi Sourav,

On Tue, Oct 15, 2013 at 06:53:46PM +0530, Sourav Poddar wrote:
> On Tuesday 15 October 2013 06:16 PM, Mark Brown wrote:
> >On Tue, Oct 15, 2013 at 05:19:07PM +0530, Sourav Poddar wrote:
> >>On Tuesday 15 October 2013 04:46 PM, Mark Brown wrote:
> >>>Can you fix this by enabling the clock is enabled when you return the
> >>>buffer to the MTD layer and then disabling the clock when the buffer is
> >>>released?
> >>Sorry, I did not get you here. With memory mapped read, there is no
> >>buffer exchanged, everything takes place at the mtd layer only, what gets
> >>exchanged is just the memory mapped address.
> >The buffer is the memory mapped address - part of getting the address
> >should be preparing the hardware for it.
> >
> >>      if (spi->mode&&  SPI_RX_MMAP) {
> >>          printk("memory mapped mode set\n");
> >>-        flash->mmap_read = true;
> >>+        flash->mmap_read = spi->memory_map;
> >So this probably needs to be a function call to get the buffer (and a
> >corresponding one to free it).
> So, the flow can be something like this:
> 
> drivers/mtd/devices/m25p80.c
> get_flash_buf()
> {
>     lock();
> 
>      t[0] = GET_BUFFER;
>      t[1] = buf;
>      ......
> 
>      spi_sync();
> 
>     unlock();
> }
> 
> mtd_read
> {
>     get_flash_buf();
> 
>     if (flash->buf) {
>         memcpy();
>        return 0;
>   }
> }
> 
> Not sure, if free buf is needed as devm_* variant is used to allocate that
> memory.

I believe you are misplacing the discussion of devm_* variants. devm_*
is only useful for resources allocated/mapped released/unmapped at probe
and release time. They do not magically remove the burden of resource
management for I/O and other dynamic operations.

In this case, you are not working at probe time, and you are not
actually allocating any memory--your 'get_flash_buf()' and corresponding
'release_flash_buf()' would not be allocating memory but would be
ensuring that the HW and driver is in the correct state.

Brian


From sourav.poddar at ti.com  Tue Oct 15 14:10:29 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 15 Oct 2013 23:40:29 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131015180142.GS23337@ld-irv-0074.broadcom.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com> <20131015180142.GS23337@ld-irv-0074.broadcom.com>
Message-ID: <525D8515.6070702@ti.com>

Hi Brian,
On Tuesday 15 October 2013 11:31 PM, Brian Norris wrote:
> Hi Sourav,
>
> On Tue, Oct 15, 2013 at 06:53:46PM +0530, Sourav Poddar wrote:
>> On Tuesday 15 October 2013 06:16 PM, Mark Brown wrote:
>>> On Tue, Oct 15, 2013 at 05:19:07PM +0530, Sourav Poddar wrote:
>>>> On Tuesday 15 October 2013 04:46 PM, Mark Brown wrote:
>>>>> Can you fix this by enabling the clock is enabled when you return the
>>>>> buffer to the MTD layer and then disabling the clock when the buffer is
>>>>> released?
>>>> Sorry, I did not get you here. With memory mapped read, there is no
>>>> buffer exchanged, everything takes place at the mtd layer only, what gets
>>>> exchanged is just the memory mapped address.
>>> The buffer is the memory mapped address - part of getting the address
>>> should be preparing the hardware for it.
>>>
>>>>       if (spi->mode&&   SPI_RX_MMAP) {
>>>>           printk("memory mapped mode set\n");
>>>> -        flash->mmap_read = true;
>>>> +        flash->mmap_read = spi->memory_map;
>>> So this probably needs to be a function call to get the buffer (and a
>>> corresponding one to free it).
>> So, the flow can be something like this:
>>
>> drivers/mtd/devices/m25p80.c
>> get_flash_buf()
>> {
>>      lock();
>>
>>       t[0] = GET_BUFFER;
>>       t[1] = buf;
>>       ......
>>
>>       spi_sync();
>>
>>      unlock();
>> }
>>
>> mtd_read
>> {
>>      get_flash_buf();
>>
>>      if (flash->buf) {
>>          memcpy();
>>         return 0;
>>    }
>> }
>>
>> Not sure, if free buf is needed as devm_* variant is used to allocate that
>> memory.
> I believe you are misplacing the discussion of devm_* variants. devm_*
> is only useful for resources allocated/mapped released/unmapped at probe
> and release time. They do not magically remove the burden of resource
> management for I/O and other dynamic operations.
>
> In this case, you are not working at probe time, and you are not
> actually allocating any memory--your 'get_flash_buf()' and corresponding
> 'release_flash_buf()' would not be allocating memory but would be
> ensuring that the HW and driver is in the correct state.
>
> Brian
Thanks for the reply. I got this.

It will be helpful if you can also comment on the thought process till 
now, as you can see from the
series that enabling quad and memory mapped support will effect both the 
SPI controller and
m25p80 side. If the changes proposed on m25p80 looks good to you.



From tpiepho at gmail.com  Tue Oct 15 14:13:38 2013
From: tpiepho at gmail.com (Trent Piepho)
Date: Tue, 15 Oct 2013 11:13:38 -0700
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131015180142.GS23337@ld-irv-0074.broadcom.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
Message-ID: <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>

On Tue, Oct 15, 2013 at 11:01 AM, Brian Norris
<computersforpeace at gmail.com> wrote:
>> So, the flow can be something like this:
>>
>> drivers/mtd/devices/m25p80.c
>> get_flash_buf()
>> {
>>     lock();
>>
>>      t[0] = GET_BUFFER;
>>      t[1] = buf;
>>      ......
>>
>>      spi_sync();
>>
>>     unlock();
>> }
>>
>> mtd_read
>> {
>>     get_flash_buf();
>>
>>     if (flash->buf) {
>>         memcpy();
>>        return 0;
>>   }
>> }
>>
>> Not sure, if free buf is needed as devm_* variant is used to allocate that
>> memory.
>
> I believe you are misplacing the discussion of devm_* variants. devm_*
> is only useful for resources allocated/mapped released/unmapped at probe
> and release time. They do not magically remove the burden of resource
> management for I/O and other dynamic operations.

Are there any numbers to show if memory mapped read support is a
benefit in Linux?  There is some question as to whether it's useful at
all or not.

If it is, I think low latency for small reads is probably one of the
only advantages.  To do that, you aren't going to want to deal with
device PM for every single read.  It would make more sense to turn the
hardware on when the MTD device is opened and leave it on until
closed.


From ezequiel.garcia at free-electrons.com  Tue Oct 15 14:29:04 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Tue, 15 Oct 2013 15:29:04 -0300
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <20131009140312.GC31294@localhost>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131009114803.GA31294@localhost> <5255455C.6060606@gmail.com>
 <20131009140312.GC31294@localhost>
Message-ID: <20131015182903.GA2454@localhost>

On Wed, Oct 09, 2013 at 11:03:13AM -0300, Ezequiel Garcia wrote:
> On Wed, Oct 09, 2013 at 02:00:28PM +0200, Daniel Mack wrote:
> > On 09.10.2013 13:48, Ezequiel Garcia wrote:
> > > On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
> > >> As part of my work to support the NAND controllers in Armada 370/XP SoC
> > >> here's a tiny set of patches to replace the currently data buffer allocation
> > >> based in a hardcoded buffer size, into a dynamic scheme.
> > >>
> > >> We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
> > >> page) and then re-allocate (either with kmalloc or using DMA allocators) using
> > >> the detected page size.
> > >>
> > >> The first patch is required to perform the initial NAND operations (READID
> > >> and friends) using programmable I/O since the DMA buffers are not ready
> > >> at such early stage.
> > >>
> > >> The second patch performs to actual dynamic allocation and it's exactly
> > >> the same patch I sent a few weeks ago:
> > >>
> > >>   http://patchwork.ozlabs.org/patch/275982/
> > >>
> > >> Daniel: Can you test these two If they look fine we can add them now,
> > >> being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.
> > > 
> > > Daniel: sorry to bother, any luck testing this?
> > 
> > Sorry for the delay, got other things to do lately ...
> > 
> 
> No problem, thanks for testing.
> 
> > I tested these two patches successfully on my board with both use_dma=0
> > and =1. Nice :) You can take my
> > 
> > 	Tested-by: Daniel Mack <zonque at gmail.com>
> > 
> 
> Good news! Brian: all yours :)
> 

Brian: any chance you pick these two soon? :-)

Thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Tue Oct 15 14:33:23 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Tue, 15 Oct 2013 18:33:23 +0000
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com> <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>

> From: Trent Piepho
> Are there any numbers to show if memory mapped read support is a
> benefit in Linux?  There is some question as to whether it's useful at
> all or not.
> 
> If it is, I think low latency for small reads is probably one of the
> only advantages.  To do that, you aren't going to want to deal with
> device PM for every single read.  It would make more sense to turn the
> hardware on when the MTD device is opened and leave it on until
> closed.
> 
+1

Therefore early suggestions were to make 'MM_MODE' as default
(if device enables it via DT). This means:
(1) switch to 'SPI_MODE' _only_ when required for commands like
 mtd_erase, etc. and switch back to 'MM_MODE' when done.
(2) And keep your controller clocks on.

This would ensure that you do minimum config-switching when using
MM_MODE. And would thus achieve low latency, and no driver intervention.

Yes, real thruput numbers would help clear the picture here ..

with regards, pekon


From richard.weinberger at gmail.com  Tue Oct 15 14:38:47 2013
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Tue, 15 Oct 2013 20:38:47 +0200
Subject: Grow UBI device?
In-Reply-To: <20131015174031.E52CF380420@gemini.denx.de>
References: <20131008192846.A25E7380A65@gemini.denx.de>
 <1381393038.7875.83.camel@sauron.fi.intel.com>
 <20131015174031.E52CF380420@gemini.denx.de>
Message-ID: <CAFLxGvzSdQUxPNK6Wxv=maPv0w-mpNGE7M18CyinS9CP+r2yqg@mail.gmail.com>

On Tue, Oct 15, 2013 at 7:40 PM, Wolfgang Denk <wd at denx.de> wrote:
> Dear Artem,
>
> In message <1381393038.7875.83.camel at sauron.fi.intel.com> you wrote:
>> Wolfgang, people already answered you, and frankly I did not read all
>> the answers :-) But here is my brief version.
>
> Thanks.
>
>> On Tue, 2013-10-08 at 21:28 +0200, Wolfgang Denk wrote:
>> > I'm looking for a clever way to migrate devices (in the field) from
>> > JFFS2 to UBI/UBIFS.  In the end result, I want to have single UBI
>> > device (which covers the whole NAND chip) with several volumes used
>> > with UBIFS.  Unfortunately I must keep some of the existing data.
>>
>> And I guess there is no temporary storage where you could copy JFFS2
>> files, re-format the flash, and copy the files back.
>
> Correct.
>
>> > It would be nice if I could start with a UBI device that is smaller
>> > than the NAND, so I can keep an existing MTD partition with a JFFS2
>> > file system.
>>
>> You mean that on the existing systems, you already have an extra MTD
>> partition, or you somehow can create one.
>>
>> Then you want to UBI/UBIFS-format the extra partition. Then copy
>> required JFFS2 files there. And then kill JFFS2 partitions and "merge"
>> them with the extra partition, and end up with UBI/UBIFS covering all
>> the space.
>
> Correct.
>
>> > Is there a way to "grow" the existing UBI device so that it now also
>> > covers the rest of the NAND chip?  Or is my only option to create a
>> > second UBI device?
>>
>> I think so, unless you use the fastmap feature. Suppose you don't.
>
> We don't.  We may want to do this later, but certainly not during this
> migration steps.
>
>> 1. Format mtd2 with UBI. Just erasing should be OK, or you can use
>> ubiformat: http://www.linux-mtd.infradead.org/faq/ubi.html#L_ubierase
>>
>> Then you attach mtd2 (ubiattach) and you get an UBI device (/dev/ubiX).
>>
>> 2. Create a volume on /dev/ubiX which spans entire UBI device
>> (ubimkvol -t AFAIR). You end up with UBI volume /dev/ubiX_0.
>>
>> 3. And here is important part - you format /dev/ubiX_0 with JFFS2 but
>> correctly.
>
> With JFFS2?  I would expect to see "UBIFS" here?

Yes, UBIFS.

>> UBIFS has this "automatic expand" feature. Which means that if the UBI
>> volume underneath it becomes larger, UBIFS will expand automatically and
>> take the entire (larger) UBI volume.
>>
>> However, there is a _limit_ to how much UBIFS can expand from the
>> original size. And you want to watch this limit and make it big enough.
>>
>> The limit is connected with the "-c" option of mkfs.ubifs. Please, check
>> the docs - they explain what exactly -c controls and how it is related
>> to the maximum UBIFS file-system size:
>>
>> http://www.linux-mtd.infradead.org/faq/ubifs.html#L_max_leb_cnt
>>
>> So, select proper -c.
>
> Thanks for the poointer.  I would have missed this.
>
>> If you do not use mkfs.ubifs, but just attach /dev/ubiX_0, the UBIFS
>> kernel driver will format the volume automatically. It will select the
>> -c value itself. Since this value is power of 2, it will just take the
>> smallest power-of-2 value. It may be OK for your purposes, may be not.
>> It is safer to use mkfs.ubifs with explicit -c.
>
> Agreed.  It would have worked in our case, as mtd1 is 32 MB and mtd2
> is 96 MB on a 128 MB NAND device, but it's much better to have full
> control.
>
>> 4. Copy important files from JFFS2-mtd1 to UBIFS-UBI-mtd2.
>>
>> 5. Erase mtd1 (or you can do this later too)
>>
>> 6. I do not know how you do this, but kill mtd1, and resize mtd2.
>> Probably mtd2 will then be named mtd1 after reboot. If you always refer
>> your MTD partitions and UBI volumes by name, you should not suffer to
>> much from mtd2 becoming mtd1.
>
> The plan is to just have another mtd3 which covers the whole device.
> So I would detach UBI from mtd2 and re-attach to mtd3.
>
>> Lets suppose there is no rename, for simplicity.
>>
>> 7. Make sure former JFFS2-mtd1 eraseblocks are erased (unless you did
>> this at step 5).
>>
>> 8. Attach mtd2 to UBI. UBI will automatically "take" the new
>> eraseblocks, erase them and write UBI headers there, and make available.
>>
>> 9. Volume size will still be the same, and you need to re-size it using
>> ubiresize.
>>
>> 10. Mount the resized volume. UBI will enlarge itself.
>
> That's just amazing :-)
>
>> Problem solved.
>>
>> Surely you do not want power cuts during this operations. If you need to
>> survive power cuts, I guess it is possible, but more complex.
>
> Thanks a lot for all the help, it's highly appreciated!
>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
> "At least they're __________EXPERIENCED incompetents"
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



-- 
Thanks,
//richard


From computersforpeace at gmail.com  Tue Oct 15 15:12:05 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 12:12:05 -0700
Subject: MTD utils v1.5.0: MEMERASE64 ioctl failed error
In-Reply-To: <201310151226.51513.vapier@gentoo.org>
References: <566CE8F1DB913147957287757DA6396B3E9D5FD4@DBDE04.ent.ti.com>
 <20131011222459.GQ23337@ld-irv-0074.broadcom.com>
 <566CE8F1DB913147957287757DA6396B3E9D6A93@DBDE04.ent.ti.com>
 <201310151226.51513.vapier@gentoo.org>
Message-ID: <20131015191205.GT23337@ld-irv-0074.broadcom.com>

On Tue, Oct 15, 2013 at 12:26:48PM -0400, Mike Frysinger wrote:
> On Tuesday 15 October 2013 04:32:23 Shah, Minal wrote:
> > Hi Brian,
> > Thanks a lot for the explanation; I understood the reason for failure.
> > 
> > > So why do you want to erase bad blocks?
> > 
> > The reason why I want to erase bad blocks is because they actually don't
> > seem to be bad. Block0 itself is shown as bad.
> > I have few partitions (like MLO and u-boot env) of size equal to 1 erase
> > block. The block is marked as bad and hence I cannot write anything to
> > this partition. One of the solutions is to increase that partition size to
> > 2 blocks so even if 1 block is bad then it will atleast be able to write
> > to the other block of the same partition. But I don't think I should do
> > this while the block is not really bad (what if all the blocks for some
> > reason are marked as bad while they are actually not).
> > 
> > This question came in my mind from the fact that "nand scrub" command is
> > allowed from u-boot which allows to also completely erase all the bad
> > blocks; so why not from the kernel level.
> 
> as mentioned, there was discussion some time ago about adding this 
> functionality.  but the work never finished.  if you're interested, i'd suggest 
> picking up the work there.

Really old work:

  http://lists.infradead.org/pipermail/linux-mtd/2010-October/032577.html

More recent discussion:

  http://thread.gmane.org/gmane.linux.drivers.mtd/41624/

There were several proposals thrown around, and we ended up in a cycle
of over-engineering suggestions. I don't really see why we can't just
implement an ioctl (MEMNUKE? MEMFORCEERASE? MEMSCRUB?) that skips the
"don't erase bad blocks" check in MEMERASE64. There may be other
reasonable alternatives, but I would warn against anything too complex.

Brian


From computersforpeace at gmail.com  Tue Oct 15 15:16:52 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 12:16:52 -0700
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <20131015182903.GA2454@localhost>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131009114803.GA31294@localhost> <5255455C.6060606@gmail.com>
 <20131009140312.GC31294@localhost>
 <20131015182903.GA2454@localhost>
Message-ID: <20131015191652.GU23337@ld-irv-0074.broadcom.com>

Hi Ezequiel,

On Tue, Oct 15, 2013 at 03:29:04PM -0300, Ezequiel Garcia wrote:
> On Wed, Oct 09, 2013 at 11:03:13AM -0300, Ezequiel Garcia wrote:
> > On Wed, Oct 09, 2013 at 02:00:28PM +0200, Daniel Mack wrote:
> > > On 09.10.2013 13:48, Ezequiel Garcia wrote:
> > > > On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
> > > >> As part of my work to support the NAND controllers in Armada 370/XP SoC
> > > >> here's a tiny set of patches to replace the currently data buffer allocation
> > > >> based in a hardcoded buffer size, into a dynamic scheme.
> > > >>
> > > >> We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
> > > >> page) and then re-allocate (either with kmalloc or using DMA allocators) using
> > > >> the detected page size.
> > > >>
> > > >> The first patch is required to perform the initial NAND operations (READID
> > > >> and friends) using programmable I/O since the DMA buffers are not ready
> > > >> at such early stage.
> > > >>
> > > >> The second patch performs to actual dynamic allocation and it's exactly
> > > >> the same patch I sent a few weeks ago:
> > > >>
> > > >>   http://patchwork.ozlabs.org/patch/275982/
> > > >>
> > > >> Daniel: Can you test these two If they look fine we can add them now,
> > > >> being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.
> > > > 
> > > > Daniel: sorry to bother, any luck testing this?
> > > 
> > > Sorry for the delay, got other things to do lately ...
> > > 
> > 
> > No problem, thanks for testing.
> > 
> > > I tested these two patches successfully on my board with both use_dma=0
> > > and =1. Nice :) You can take my
> > > 
> > > 	Tested-by: Daniel Mack <zonque at gmail.com>
> > > 
> > 
> > Good news! Brian: all yours :)
> > 
> 
> Brian: any chance you pick these two soon? :-)

I think I overlooked these once your other gigantic patch set came. I'll
take a look at them now.

Brian


From computersforpeace at gmail.com  Tue Oct 15 15:41:59 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 12:41:59 -0700
Subject: [PATCH 2/2] mtd: nand: pxa3xx: Allocate data buffer on
 detected flash size
In-Reply-To: <1380911438-24240-3-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1380911438-24240-3-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131015194159.GV23337@ld-irv-0074.broadcom.com>

On Fri, Oct 04, 2013 at 03:30:38PM -0300, Ezequiel Garcia wrote:
> This commit replaces the currently hardcoded buffer size, by a
> dynamic detection scheme. First a small 256 bytes buffer is allocated
> so the device can be detected (using READID and friends commands).
> 
> After detection, this buffer is released and a new buffer is allocated
> to acommodate the page size plus out-of-band size.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/nand/pxa3xx_nand.c | 45 ++++++++++++++++++++++++++++--------------
>  1 file changed, 30 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> index a47c67f..bfb2b9f 100644
> --- a/drivers/mtd/nand/pxa3xx_nand.c
> +++ b/drivers/mtd/nand/pxa3xx_nand.c
> @@ -39,6 +39,13 @@
>  #define NAND_STOP_DELAY		(2 * HZ/50)
>  #define PAGE_CHUNK_SIZE		(2048)
>  
> +/*
> + * Define a buffer size for the initial command that detects the flash device:
> + * STATUS, READID and PARAM. The largest of these is the PARAM command,
> + * needing 256 bytes.
> + */
> +#define INIT_BUFFER_SIZE	256
> +

Actually, PARAM tries to get 768 bytes in nand_base.c to retrieve the
redundant copies, but your current driver implementation seems to ignore
the 2nd and 3rd parameter pages by returning 0xFF.

So this is not a criticism of the current patch, but you may want to
consider improving your NAND_CMD_PARAM support (also, you don't support
NAND_CMD_RNDOUT, which is now used for extended parameter page support).

>  /* registers and bit definitions */
>  #define NDCR		(0x00) /* Control register */
>  #define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */

[snip]

Otherwise, this patch looks good.

Brian


From computersforpeace at gmail.com  Tue Oct 15 16:47:41 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 15 Oct 2013 13:47:41 -0700
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131015204741.GW23337@ld-irv-0074.broadcom.com>

Hi Ezequiel,

On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
> As part of my work to support the NAND controllers in Armada 370/XP SoC
> here's a tiny set of patches to replace the currently data buffer allocation
> based in a hardcoded buffer size, into a dynamic scheme.
> 
> We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
> page) and then re-allocate (either with kmalloc or using DMA allocators) using
> the detected page size.
> 
> The first patch is required to perform the initial NAND operations (READID
> and friends) using programmable I/O since the DMA buffers are not ready
> at such early stage.
> 
> The second patch performs to actual dynamic allocation and it's exactly
> the same patch I sent a few weeks ago:
> 
>   http://patchwork.ozlabs.org/patch/275982/
> 
> Daniel: Can you test these two If they look fine we can add them now,
> being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.

Thanks for sending these out separately from your other series. They are
independently useful and look good to me. And thanks, Daniel, for the
testing.

Pushed to l2-mtd.git!

Brian


From broonie at kernel.org  Tue Oct 15 16:52:54 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 21:52:54 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
References: <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
Message-ID: <20131015205254.GX2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 06:33:23PM +0000, Gupta, Pekon wrote:

> Therefore early suggestions were to make 'MM_MODE' as default
> (if device enables it via DT). This means:
> (1) switch to 'SPI_MODE' _only_ when required for commands like
>  mtd_erase, etc. and switch back to 'MM_MODE' when done.
> (2) And keep your controller clocks on.

This sounds like a policy decision, I don't see any reason for it to be
in DT.  What works well with one application stack may not be the best
choice for another and future developments may change what's most
sensible for a given system, it shouldn't be fixed in the DT.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/639d725e/attachment-0001.sig>

From broonie at kernel.org  Tue Oct 15 16:59:52 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 21:59:52 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
References: <20131010101410.GG21581@sirena.org.uk> <52568AA3.9080203@ti.com>
 <20131011100839.GA21581@sirena.org.uk> <525CDB77.4040201@ti.com>
 <20131015111647.GX2443@sirena.org.uk> <525D2BB3.4020705@ti.com>
 <20131015124656.GM2443@sirena.org.uk> <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
Message-ID: <20131015205952.GY2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 11:13:38AM -0700, Trent Piepho wrote:

> If it is, I think low latency for small reads is probably one of the
> only advantages.  To do that, you aren't going to want to deal with
> device PM for every single read.  It would make more sense to turn the
> hardware on when the MTD device is opened and leave it on until
> closed.

Autosuspend *might* be efficient enough.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/1f025092/attachment.sig>

From tpiepho at gmail.com  Tue Oct 15 17:03:01 2013
From: tpiepho at gmail.com (Trent Piepho)
Date: Tue, 15 Oct 2013 14:03:01 -0700
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131015205254.GX2443@sirena.org.uk>
References: <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <20131015205254.GX2443@sirena.org.uk>
Message-ID: <CA+7tXijF8VTsA3Mk3j8Qe7r0nqr+Xri6=GDfEZGH74Doup5=eA@mail.gmail.com>

On Tue, Oct 15, 2013 at 1:52 PM, Mark Brown <broonie at kernel.org> wrote:
> On Tue, Oct 15, 2013 at 06:33:23PM +0000, Gupta, Pekon wrote:
>
>> Therefore early suggestions were to make 'MM_MODE' as default
>> (if device enables it via DT). This means:
>> (1) switch to 'SPI_MODE' _only_ when required for commands like
>>  mtd_erase, etc. and switch back to 'MM_MODE' when done.
>> (2) And keep your controller clocks on.
>
> This sounds like a policy decision, I don't see any reason for it to be
> in DT.  What works well with one application stack may not be the best
> choice for another and future developments may change what's most
> sensible for a given system, it shouldn't be fixed in the DT.

I could see the driver using the transfer size to decide, memory
mapped or SPI with DMA.  Small transfers via memory mapped access and
larger would use DMA.  The spi-mxs driver does this to decide PIO or
DMA.  The threshold size is hard coded in the driver.  If you wanted
to be able to change it, I would think a sysfs attribute would be the
way to do that.

It does get tricky when you're dealing with flash roms, as people
often want to boot from those really fast, so you want the kernel to
know how to use them in the fastest way before it boots as opposed to
after booting when it's obviously too late to configure the kernel to
boot faster.


From broonie at kernel.org  Tue Oct 15 18:10:52 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 15 Oct 2013 23:10:52 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXijF8VTsA3Mk3j8Qe7r0nqr+Xri6=GDfEZGH74Doup5=eA@mail.gmail.com>
References: <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <20131015205254.GX2443@sirena.org.uk>
 <CA+7tXijF8VTsA3Mk3j8Qe7r0nqr+Xri6=GDfEZGH74Doup5=eA@mail.gmail.com>
Message-ID: <20131015221052.GB2443@sirena.org.uk>

On Tue, Oct 15, 2013 at 02:03:01PM -0700, Trent Piepho wrote:

> It does get tricky when you're dealing with flash roms, as people
> often want to boot from those really fast, so you want the kernel to
> know how to use them in the fastest way before it boots as opposed to
> after booting when it's obviously too late to configure the kernel to
> boot faster.

I'd guess that having fast as the default would be sane enough, though.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131015/2a820feb/attachment.sig>

From ezequiel.garcia at free-electrons.com  Wed Oct 16 06:25:58 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 16 Oct 2013 07:25:58 -0300
Subject: [PATCH 2/2] mtd: nand: pxa3xx: Allocate data buffer on detected
 flash size
In-Reply-To: <20131015194159.GV23337@ld-irv-0074.broadcom.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1380911438-24240-3-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131015194159.GV23337@ld-irv-0074.broadcom.com>
Message-ID: <20131016102557.GA2518@localhost>

On Tue, Oct 15, 2013 at 12:41:59PM -0700, Brian Norris wrote:
> On Fri, Oct 04, 2013 at 03:30:38PM -0300, Ezequiel Garcia wrote:
> > This commit replaces the currently hardcoded buffer size, by a
> > dynamic detection scheme. First a small 256 bytes buffer is allocated
> > so the device can be detected (using READID and friends commands).
> > 
> > After detection, this buffer is released and a new buffer is allocated
> > to acommodate the page size plus out-of-band size.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/nand/pxa3xx_nand.c | 45 ++++++++++++++++++++++++++++--------------
> >  1 file changed, 30 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> > index a47c67f..bfb2b9f 100644
> > --- a/drivers/mtd/nand/pxa3xx_nand.c
> > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> > @@ -39,6 +39,13 @@
> >  #define NAND_STOP_DELAY		(2 * HZ/50)
> >  #define PAGE_CHUNK_SIZE		(2048)
> >  
> > +/*
> > + * Define a buffer size for the initial command that detects the flash device:
> > + * STATUS, READID and PARAM. The largest of these is the PARAM command,
> > + * needing 256 bytes.
> > + */
> > +#define INIT_BUFFER_SIZE	256
> > +
> 
> Actually, PARAM tries to get 768 bytes in nand_base.c to retrieve the
> redundant copies, but your current driver implementation seems to ignore
> the 2nd and 3rd parameter pages by returning 0xFF.
> 
> So this is not a criticism of the current patch, but you may want to
> consider improving your NAND_CMD_PARAM support (also, you don't support
> NAND_CMD_RNDOUT, which is now used for extended parameter page support).
> 

Ah, good input. I'll research a bit more and try to cook a patch, it doesn't
sound like a lot of work, and it would be nice to have better command support.

Thanks,
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Wed Oct 16 07:05:39 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 16 Oct 2013 08:05:39 -0300
Subject: [PATCH 0/2] pxa3xx: Data buffer dynamic allocation
In-Reply-To: <20131015204741.GW23337@ld-irv-0074.broadcom.com>
References: <1380911438-24240-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131015204741.GW23337@ld-irv-0074.broadcom.com>
Message-ID: <20131016110538.GB2518@localhost>

On Tue, Oct 15, 2013 at 01:47:41PM -0700, Brian Norris wrote:
> Hi Ezequiel,
> 
> On Fri, Oct 04, 2013 at 03:30:36PM -0300, Ezequiel Garcia wrote:
> > As part of my work to support the NAND controllers in Armada 370/XP SoC
> > here's a tiny set of patches to replace the currently data buffer allocation
> > based in a hardcoded buffer size, into a dynamic scheme.
> > 
> > We first use kmalloc to request a 256 bytes (big enough for the ONFI paramater
> > page) and then re-allocate (either with kmalloc or using DMA allocators) using
> > the detected page size.
> > 
> > The first patch is required to perform the initial NAND operations (READID
> > and friends) using programmable I/O since the DMA buffers are not ready
> > at such early stage.
> > 
> > The second patch performs to actual dynamic allocation and it's exactly
> > the same patch I sent a few weeks ago:
> > 
> >   http://patchwork.ozlabs.org/patch/275982/
> > 
> > Daniel: Can you test these two If they look fine we can add them now,
> > being an improvement to the driver pxa3xx beyond the Armada 370/XP effort.
> 
> Thanks for sending these out separately from your other series. They are
> independently useful and look good to me. And thanks, Daniel, for the
> testing.
> 
> Pushed to l2-mtd.git!
> 

Great, thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From broonie at kernel.org  Wed Oct 16 08:16:14 2013
From: broonie at kernel.org (Mark Brown)
Date: Wed, 16 Oct 2013 13:16:14 +0100
Subject: [PATCH] mtd: dataflash: Say if we find a device we don't support
Message-ID: <1381925774-10301-1-git-send-email-broonie@kernel.org>

From: Mark Brown <broonie at linaro.org>

Ensure that the error message if we identify a flash we don't know how to
talk to is displayed on the console in order to aid diagnostics. While
we're at convert the message to use dev_info() rather than our hand rolled
version of it for consistency.

Signed-off-by: Mark Brown <broonie at linaro.org>
---
 drivers/mtd/devices/mtd_dataflash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 1cfbfcf..4a47b02 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -879,7 +879,7 @@ static int dataflash_probe(struct spi_device *spi)
 		break;
 	/* obsolete AT45DB1282 not (yet?) supported */
 	default:
-		pr_debug("%s: unsupported device (%x)\n", dev_name(&spi->dev),
+		dev_info(&spi->dev, "unsupported device (%x)\n",
 				status & 0x3c);
 		status = -ENODEV;
 	}
-- 
1.8.4.rc3



From dave.kleikamp at oracle.com  Wed Oct 16 10:04:45 2013
From: dave.kleikamp at oracle.com (Dave Kleikamp)
Date: Wed, 16 Oct 2013 09:04:45 -0500
Subject: [PATCH V9 32/33] ubifs: convert file ops from aio_read/write to
 read/write_iter
In-Reply-To: <1381932286-14978-1-git-send-email-dave.kleikamp@oracle.com>
References: <1381932286-14978-1-git-send-email-dave.kleikamp@oracle.com>
Message-ID: <1381932286-14978-33-git-send-email-dave.kleikamp@oracle.com>

Signed-off-by: Dave Kleikamp <dave.kleikamp at oracle.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/file.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 123c79b..22924e0 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -44,7 +44,7 @@
  * 'ubifs_writepage()' we are only guaranteed that the page is locked.
  *
  * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the
- * read-ahead path does not lock it ("sys_read -> generic_file_aio_read ->
+ * read-ahead path does not lock it ("sys_read -> generic_file_read_iter ->
  * ondemand_readahead -> readpage"). In case of readahead, @I_SYNC flag is not
  * set as well. However, UBIFS disables readahead.
  */
@@ -1396,8 +1396,8 @@ static int update_mctime(struct ubifs_info *c, struct inode *inode)
 	return 0;
 }
 
-static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov,
-			       unsigned long nr_segs, loff_t pos)
+static ssize_t ubifs_write_iter(struct kiocb *iocb, struct iov_iter *iter,
+				loff_t pos)
 {
 	int err;
 	struct inode *inode = iocb->ki_filp->f_mapping->host;
@@ -1407,7 +1407,7 @@ static ssize_t ubifs_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	if (err)
 		return err;
 
-	return generic_file_aio_write(iocb, iov, nr_segs, pos);
+	return generic_file_write_iter(iocb, iter, pos);
 }
 
 static int ubifs_set_page_dirty(struct page *page)
@@ -1583,8 +1583,8 @@ const struct file_operations ubifs_file_operations = {
 	.llseek         = generic_file_llseek,
 	.read           = do_sync_read,
 	.write          = do_sync_write,
-	.aio_read       = generic_file_aio_read,
-	.aio_write      = ubifs_aio_write,
+	.read_iter       = generic_file_read_iter,
+	.write_iter      = ubifs_write_iter,
 	.mmap           = ubifs_file_mmap,
 	.fsync          = ubifs_fsync,
 	.unlocked_ioctl = ubifs_ioctl,
-- 
1.8.4



From pekon at ti.com  Wed Oct 16 14:48:36 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 16 Oct 2013 18:48:36 +0000
Subject: [PATCH v9 0/9] mtd:nand:omap2: clean-up of supported ECC schemes
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA277C8@DBDE04.ent.ti.com>

Hi Brian,

> 
> *changes v8 -> v9*
> [PATCH 1/9] <no update from [PATCH v8 1/6]>
> [PATCH 2/9] <only commit log updated from [PATCH v8 2/6]>
>  As per feedbacks from Brian Norris <computersforpeace at gmail.com>
> previous
>  revision [PATCH v8 3/6] and [PATCH 4/6] are split into following sub-patches:
> - [PATCH 3/9] <new> replaces local reference with generic names (mtd,
> nand_chip)
> - [PATCH 4/9] <new> enables auto-detection of bus-width
> - [PATCH 5/9] <new> removes omap3_init_bch: populates ecc-scheme data
> - [PATCH 6/9] <new> removes omap3_init_bch_tail: populates ecc-layout
> - [PATCH 7/9] <new> replaces lib/bch.c with nand_bch.c wrapper
> [PATCH 8/9] <no update same as [PATCH v8 5/6]
> [PATCH 9/9] removed devm_free_xx functions
> 

Request you to have a look at v9.
If this is acceptable, then I would work to rebase the other pending
series on top of this one.


with regards, pekon


From ezequiel.garcia at free-electrons.com  Wed Oct 16 16:23:49 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 16 Oct 2013 17:23:49 -0300
Subject: [PATCH 03/21] mtd: nand: pxa3xx: Use a completion to signal
 device ready
In-Reply-To: <20131004185454.GA20476@localhost>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-4-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131002215628.GW23337@ld-irv-0074.broadcom.com>
 <20131004185454.GA20476@localhost>
Message-ID: <20131016202348.GA3232@localhost>

On Fri, Oct 04, 2013 at 03:54:54PM -0300, Ezequiel Garcia wrote:
> Brian,
> 
> First of all: thanks for all your nice feedback.
> I'm going through all of it right now, and just started
> by this one.
> 
> On Wed, Oct 02, 2013 at 02:56:28PM -0700, Brian Norris wrote:
> > On Thu, Sep 19, 2013 at 01:01:27PM -0300, Ezequiel Garcia wrote:
> > > Apparently, the expected behavior of the waitfunc() NAND chip call
> > > is to wait for the device to be READY (this is a standard chip line).
> > > However, the current implementation does almost nothing, which opens
> > > a possibility to issue a command to a non-ready device.
> > > 
> > > Fix this by adding a new completion to wait for the ready event to arrive.
> > > 
> > > Because the "is ready" flag is cleared from the controller status
> > > register, it's needed to store that state in the driver, and because the
> > > field is accesed from an interruption, the field needs to be of an
> > > atomic type.
> > 
> > Does it really need to be an atomic type? AIUI, you can hand off exclusive
> > control to the hardware when you begin a command. So the rest of the driver would be
> > inactive when the IRQ handler is setting the ready flag. And similarly,
> > the hardware should be inactive (i.e., no interrupts) when you are
> > modifying the ready flag in the driver (i.e., in cmdfunc).
> > 
> 
> Hm... I think that's not the case, and that's exactly why I had to add
> an atomic type. See below.
> 
> > Or perhaps I'm misunderstanding something.
> > 
> > > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > > ---
> > >  drivers/mtd/nand/pxa3xx_nand.c | 45 +++++++++++++++++++++++++++++-------------
> > >  1 file changed, 31 insertions(+), 14 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> > > index a8d2ea7..fba91c2 100644
> > > --- a/drivers/mtd/nand/pxa3xx_nand.c
> > > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> > > @@ -35,6 +35,7 @@
> > >  
> > >  #include <linux/platform_data/mtd-nand-pxa3xx.h>
> > >  
> > > +#define NAND_DEV_READY_TIMEOUT  50
> > >  #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
> > >  #define NAND_STOP_DELAY		(2 * HZ/50)
> > >  #define PAGE_CHUNK_SIZE		(2048)
> > > @@ -167,7 +168,7 @@ struct pxa3xx_nand_info {
> > >  	struct clk		*clk;
> > >  	void __iomem		*mmio_base;
> > >  	unsigned long		mmio_phys;
> > > -	struct completion	cmd_complete;
> > > +	struct completion	cmd_complete, dev_ready;
> > 
> > Do you really need two completion structures? Does 'device ready' always
> > follow 'command complete', so that you can just use 'device ready' all
> > the time? And if so, does it make sense to just use dev_ready?
> > 
> > >  
> > >  	unsigned int 		buf_start;
> > >  	unsigned int		buf_count;
> 
> The idea here is to handle the following situation. After a command is
> completed (which also applies to the 'chunked' page command we want to
> support later in the patchset) the controller sets a 'command done' flag
> in the ISR.
> 
> The interruption handler calls the command done completion which causes
> the cmdfunc to finish waiting and exit (or continue executing commands
> in the 'chunked' case).
> 
> Notice that this does *not* guarantee the controller is ready since the
> 'ready' flag is independent of the 'command complete' flag and the IRQ can
> arrive at any later point.
> 
> Let's suppose the cmdfunc() has exited, and the NAND base code is going to
> continue the operation. In the PAGEPROG case, the NAND base calls waitfunc()
> before continuing the operation.
> 
> At that point, we **need** to wait for the 'ready' flag because otherwise
> the NAND base could issue another PAGEPROG command, while the controller
> is not really ready to receive it.
> 
> However, if we enter the waitfunc() we want to read the info->is_ready flag
> to check the completion has been initialized and a wait is suitable.
> Otherwise, some commands that are not issued (with no wait completion
> initialized) will stall at that waitfunc().
> 
> While at the waitfunc() the interruption handler might get called for
> the 'ready' flag and so the info->is_ready variable gets access from two
> different execution contexts.
> 
> Given the above behavior, I thought the only way of dealing with this
> was to add a new completion and use atomic type for the is_ready flag.
> 
> Is the above clear? Do you think the implementation is correct for the
> behavior?

Brian:

I'm picking up on my NAND work, and wanted to know if you have any
comments about this patch. Otherwise, I'll just leave it as it is.

FWIW, any comments about the locking scheme is always highly appreciated
as it's a complex and important issue, so feel free to ask any questions
or suggest any improvements.

Thanks,
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Wed Oct 16 17:30:24 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 14:30:24 -0700
Subject: [PATCH v9 3/9] mtd: nand: omap: cleanup: replace local
 references with generic framework names
In-Reply-To: <1381816197-20477-4-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-4-git-send-email-pekon@ti.com>
Message-ID: <20131016213024.GY23337@ld-irv-0074.broadcom.com>

Hi Pekon,

On Tue, Oct 15, 2013 at 11:19:51AM +0530, Pekon Gupta wrote:
> This patch updates following in omap_nand_probe() and omap_nand_remove()
> - replaces "info->nand" with "nand_chip" (struct nand_chip *nand_chip)
> - replaces "info->mtd" with "mtd" (struct mtd_info *mtd)
> - white-space and formatting cleanup
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

This patch looks good. Thanks for being consistent.

> ---
>  drivers/mtd/nand/omap2.c | 112 ++++++++++++++++++++++++-----------------------
>  1 file changed, 57 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 8d521aa..5596368 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c

...

> @@ -1846,17 +1848,16 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	spin_lock_init(&info->controller.lock);
>  	init_waitqueue_head(&info->controller.wq);
>  
> -	info->pdev = pdev;
> -
> +	info->pdev		= pdev;
>  	info->gpmc_cs		= pdata->cs;
>  	info->reg		= pdata->reg;
> -
> -	info->mtd.priv		= &info->nand;
> -	info->mtd.name		= dev_name(&pdev->dev);
> -	info->mtd.owner		= THIS_MODULE;
> -
> -	info->nand.options	= pdata->devsize;
> -	info->nand.options	|= NAND_SKIP_BBTSCAN;
> +	mtd			= &info->mtd;
> +	mtd->priv		= &info->nand;
> +	mtd->name		= dev_name(&pdev->dev);
> +	mtd->owner		= THIS_MODULE;
> +	nand_chip		= &info->nand;
> +	nand_chip->options	= pdata->devsize;

Trivial side comment: the 'devsize' field is not named very
informatively. It is apparently just a way to specify nand_chip.options,
and it is only actually used for setting a buswidth. (It is also badly
named nand_type in other places.) Not sure if it's worth improving, or
even dropping at some later point in time.

> +	nand_chip->options	|= NAND_SKIP_BBTSCAN;
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  	info->of_node		= pdata->of_node;
>  #endif

[...]

Brian


From computersforpeace at gmail.com  Wed Oct 16 18:22:48 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 15:22:48 -0700
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <1381816197-20477-5-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
Message-ID: <20131016222248.GZ23337@ld-irv-0074.broadcom.com>

On Tue, Oct 15, 2013 at 11:19:52AM +0530, Pekon Gupta wrote:
> Autodetection of NAND device bus-width was added in generic NAND driver as
> part of following commit
> 	commit 64b37b2a63eb2f80b65c7185f0013f8ffc637ae3
> 	Author:     Matthieu CASTET <matthieu.castet at parrot.com>
> 	AuthorDate: 2012-11-06
> 	mtd: nand: add NAND_BUSWIDTH_AUTO to autodetect bus width
> This patch enables this feature for OMAP2 NAND driver
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/omap2.c | 29 ++++++++++++++++-------------
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 5596368..57a3f51 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c

[...]

> @@ -1904,6 +1903,21 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->chip_delay = 50;
>  	}
>  
> +	/* scan for NAND device connected to chip controller */
> +	if (nand_scan_ident(mtd, 1, NULL)) {
> +		err = -ENXIO;
> +		goto out_release_mem_region;
> +	}
> +	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
> +			(pdata->devsize & NAND_BUSWIDTH_16)) {
> +		pr_err("%s: detected %s device but driver configured for %s\n",
> +			DRIVER_NAME,
> +			(nand_chip->options & NAND_BUSWIDTH_16) ? "x16" : "x8",
> +			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" : "x8");

I'm not sure on the policy choice here; if you're using BUSWIDTH_AUTO,
do you even want to try to configure the buswidth by platform data?
You're not really getting the full use out of NAND_BUSWIDTH_AUTO because
the platform data has to guess the same buswidth that nand_base.c
determines. This is worse than the previous behavior, in which you would
try both buswidths if the specified type failed.

IOW, what are you trying to achieve with auto-buswidth? Automatic
determination of the buswidth or just automatic validation? What do you
achieve with platform data's selection of buswidth? Specification of the
buswidth or just a hint? Do the goals conflict? Perhaps you can just
warn, and not error out if the two selections don't match? Or maybe you
really wanted to replace the platform data selection mechanism entirely
with auto-buswidth?

> +		err = -EINVAL;
> +		goto out_release_mem_region;
> +	}
> +
>  	switch (pdata->xfer_type) {
>  	case NAND_OMAP_PREFETCH_POLLED:
>  		nand_chip->read_buf   = omap_read_buf_pref;

[...]

Brian


From ezequiel.garcia at free-electrons.com  Wed Oct 16 19:29:16 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 16 Oct 2013 20:29:16 -0300
Subject: [PATCH 00/21] Armada 370/XP NAND support
In-Reply-To: <20131005000649.GZ23337@ld-irv-0074.broadcom.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20130926195615.GK23337@ld-irv-0074.broadcom.com>
 <20130930122428.GA2417@localhost>
 <20131003000253.GX23337@ld-irv-0074.broadcom.com>
 <20131004194203.GB20476@localhost>
 <20131005000649.GZ23337@ld-irv-0074.broadcom.com>
Message-ID: <20131016232916.GA5362@localhost>

Brian,

Let's continue the discussion about this controller and its ECC engine.

Sorry for the delayed reply. Also please bare with me as I'm not an MTD,
NAND or ECC expert; so feel free to correct any mis-understandings on
my side.

On Fri, Oct 04, 2013 at 05:06:49PM -0700, Brian Norris wrote:
> On Fri, Oct 04, 2013 at 04:42:04PM -0300, Ezequiel Garcia wrote:
> > On Wed, Oct 02, 2013 at 05:02:53PM -0700, Brian Norris wrote:
> > > On Mon, Sep 30, 2013 at 09:24:29AM -0300, Ezequiel Garcia wrote:
> > > > Notice that this means you can control the ECC strength: since the ECC
> > > > is always 30B, and it's calculated on the transfered chunk you can
> > > > configure the controller to transfer the page in 1024B chunks and get a
> > > > 30B ECC for each of this chunk, thus doubling the ECC strength.
> > > 
> > > This is a little odd. Your ECC HW is not parameterized by ECC strength,
> > > but instead by ECC sector size? I think I have some comments for patch
> > > 5, relevant to this topic.
> > > 
> > 
> > Indeed. When ECC engine in the controller is set to do BCH, it always
> > store a 30-byte ECC code. This 30-byte code is calculated on the
> > transfered chunk, and since the chunk size is configurable we can
> > effectively configure the ECC strength.
> > 
> > The specification says
> 
> Is there a public URL for the specification?
> 

Not yet, but we're working very hard to get the spec to be published.

> > the ECC BCH engine can correct up to 16-bits, which means:
> 
> Is this your interpretation, or are you quoting the spec?
> 

I'm quoting the spec.

> > if the chunk is 2048 bytes you get BCH-4, and if the chunk
> > is set to be 1024 bytes, you get BCH-8.
> 
> That doesn't really make sense to me. If you can't post a public URL,
> can you paste the relevant text for this?
> 

I guess the above is not clear: I didn't mean BCH-4 or BCH-8 over any region.
Instead, I meant that: the spec says the ECC BCH engine can correct up to 16 bits
'per region', where 'region' is the amount of data the controller is
configured to transfer (which is arbitrary).

So, if you set the controller to transfer 2048B you can correct up to 16
bits on this 2048B region, or 4 bits per 512B, hence BCH-4.

If you set the controller to transfer 1024B you can correct up to 16
bits on this 1024B region, or 8 bits per 512B, hence BCH-8.

> Most NAND specifies a required correctability of something like "correct
> 1 bit error per 512 bytes" or "correct 4 bits per 512 bytes". These are
> not the same as "correct 1 bit per 2048 bytes" and "correct 4 bits per
> 2048 bytes", respectively, for obvious reasons.
> 
> So your "BCH-4" over a "2048 byte chunk" could be interpreted in
> multiple ways. I'll list a few.
> 
> (1) BCH-4 usually means 4 bit correction over a 512 byte region, to
>     match most SLC that might specify 4-bit correction. Applied to your
>     hardware, it could possibly be that the 2048 byte region is actually
>     4 smaller regions which are corrected separately, each with 4 bit
>     correction. The ECC metadata just happens to be stored in 30 bytes
>     of OOB (each 512-byte "sub-step" uses 7.5 bytes of spare area??)
> 
>     Another way to look at this: perhaps your ECC "chunk size" (the
>     contiguous region over which your ECC is applied and transferred
>     atomically) is different than the "correction region" (the region
>     over which a certain number of bits may be corrected).
> 

Yes, the above (1) matches this hardware, expect for one point. The
specifications says that "the BCH engine corrects up to 16 errors
over the entire page". So there aren't any "smaller" regions, and the
hardware operates on the entire page.

However, the BCH does not operate on the "page" but rather on the
transfered region (which is configurable). So, as I explained above,
you can actually correct 16 bits per 2048B or 16 bits per 1024B depending
on the way you configure the controller.

Is this clearer now?

> 
> Barring more lucid documentation, you might want to verify this with
> some tests. If you can support raw (no ECC) programming, this is a case
> where you could induce bit errors and see how many can be corrected in
> various patterns. But that's only necessary if your documentation sucks
> too badly or is not public.
> 

Hm.. I'll see if I can do this. It sounds like an interesting test.

> Regarding patch 5 (might as well mention it here), you are only checking
> the ecc_strength_ds field for 4. You are not checking ecc_step_ds, which
> likely will be 512 or 1024. Both parameters are relevant to determining
> what ECC types are strong enough.

Yup, those checks are really crappy in this v1, I have a v2 ready to be
submitted that takes care of this in a much cleaner (and safer way).

> But it's confusing enough right now to
> even determine what your hardware means when you say "BCH-4", so we
> might not be ready to handle this yet...
> 

Regarding this: I'd really like to understand better this 'step' concept
and it applicability on this controller. So any clarification is welcome :)

As far as I can see: currently the hardware does ECC corrections in a
completely transparent fashion and merely 'reports' the no. of corrected
bits through some IRQ plus some registers.
Therefore, it implements the ecc.{read,write}_page() functions.

So, why should I tell the NAND core any of the ECC details?

I see other drivers need to implement some of the functions in the
nand_ecc_ctrl struct, such as: hwctl(), calculate() or correct().
However, I can't see how any of that applies on this controller.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Wed Oct 16 21:58:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 18:58:54 -0700
Subject: [PATCH v9 5/9] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW
 ECC configurations in device_probe
In-Reply-To: <1381816197-20477-6-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-6-git-send-email-pekon@ti.com>
Message-ID: <20131017015854.GA23337@ld-irv-0074.broadcom.com>

On Tue, Oct 15, 2013 at 11:19:53AM +0530, Pekon Gupta wrote:
> current implementation in omap3_init_bch() has some redundant code like:
> (1) omap3_init_bch() re-probes the DT-binding to detect presence of ELM h/w
>     engine on SoC. And based on that it selects implemetation of ecc-scheme.
>     However, this is already done as part of GPMC DT parsing.
> (2) As omap3_init_bch() serves as common function for configuring all types of
>     BCHx ecc-schemes, so there are multiple levels of redudant if..then..else
>     checks while populating nand_chip->ecc.
> 
> This patch make following changes to OMAP NAND driver:
> (1) removes omap3_init_bch(): each ecc-scheme is individually configured in
>     omap_nand_probe() there by removing redundant if..then..else checks.
> (2) adds is_elm_present(): re-probing of ELM device via DT is not required as
>     it's done in GPMC driver probe. Thus is_elm_present() just initializes ELM
>     driver with NAND probe data, when ecc-scheme with h/w based error-detection
>     is used.
> (3) separates out configuration of different flavours of "BCH4" and "BCH8"
>     ecc-schemes as given in below table
> (4) conditionally compiles callbacks implementations of ecc.hwctl(),
>     ecc.calculate(), ecc.correct() to avoid warning of un-used functions.
> 
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
> | (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
> |                                       |               |               |
> |OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> | (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
> |        ti,elm-id)                     |               |               |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
> | (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
> |                                       |               |               |
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> | (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
> |        ti,elm-id)                     |               |               |
> +---------------------------------------+---------------+---------------+
> 
> - 'CONFIG_MTD_NAND_ECC_BCH' is generic KConfig required to build lib/bch.c
>     which is required for ECC error detection done in software.
>     (mainly used for legacy platforms which do not have on-chip ELM engine)
> 
> - 'CONFIG_MTD_NAND_OMAP_BCH' is OMAP specific Kconfig to detemine presence
>     on ELM h/w engine on SoC.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

This patch looks good to me.

Brian


From computersforpeace at gmail.com  Wed Oct 16 22:06:58 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 19:06:58 -0700
Subject: [PATCH v9 6/9] mtd: nand: omap: clean-up ecc layout for BCH
 ecc schemes
In-Reply-To: <1381816197-20477-7-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-7-git-send-email-pekon@ti.com>
Message-ID: <20131017020658.GB23337@ld-irv-0074.broadcom.com>

On Tue, Oct 15, 2013 at 11:19:54AM +0530, Pekon Gupta wrote:
> In current implementation omap3_init_bch_tail() is a common function to
> define ecc layout for different BCHx ecc schemes.This patch:
> (1) removes omap3_init_bch_tail() and defines ecc layout for individual
>     ecc-schemes along with populating their nand_chip->ecc data in
>     omap_nand_probe(). This improves the readability and scalability of
>     code for add new ecc schemes in future.
> (2) removes 'struct nand_bbt_descr bb_descrip_flashbased' because default
>     nand_bbt_descr in nand_bbt.c matches the same (.len=1 for x8 devices).
> (3) add the check to see if NAND device has enough OOB/Spare bytes to
>     store ECC signature of whole page, as defined by ecc-scheme.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

This patch also looks OK.

Brian


From computersforpeace at gmail.com  Wed Oct 16 22:22:37 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 19:22:37 -0700
Subject: [PATCH v9 7/9] mtd: nand: omap: use
 drivers/mtd/nand/nand_bch.c wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <1381816197-20477-8-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-8-git-send-email-pekon@ti.com>
Message-ID: <20131017022237.GC23337@ld-irv-0074.broadcom.com>

+ Ivan, as he has touched this stuff before

On Tue, Oct 15, 2013 at 11:19:55AM +0530, Pekon Gupta wrote:
> generic frame-work in mtd/nand/nand_bch.c is a wrapper above lib/bch.h which
> encapsulates all control information specific to BCH ecc algorithm in software.
> Thus this patch:
> (1) replace omap specific implementations with equivalent wrapper in nand_bch.c
>     so that more generic code is re-used. like;
>         omap3_correct_data_bch() -> nand_bch_correct_data()
>         omap3_free_bch() -> nand_bch_free()
> (2) replace direct calls to lib/bch.c with wrapper functions defined in nand_bch.c
> 	init_bch() -> nand_bch_init()
> (3) removes selection between BCH8 and BCH4 h/w ecc-schemes via KConfig.
>     This selection is now based on ti,nand-ecc-opt and ti,elm-id DT bindings.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/Kconfig | 30 ++-------------
>  drivers/mtd/nand/omap2.c | 96 +++++++++++-------------------------------------
>  2 files changed, 26 insertions(+), 100 deletions(-)
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index d885298..5836039 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
>  
>  config MTD_NAND_OMAP_BCH
>  	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
> -	tristate "Enable support for hardware BCH error correction"
> +	tristate "Support hardware based BCH error correction"
>  	default n
>  	select BCH
> -	select BCH_CONST_PARAMS

Do you know what will happen now if someone configures BCH_CONST_PARAMS?
Would this cause problems?

>  	help
> -	 Support for hardware BCH error correction.
> -
> -choice
> -	prompt "BCH error correction capability"
> -	depends on MTD_NAND_OMAP_BCH
> -
> -config MTD_NAND_OMAP_BCH8
> -	bool "8 bits / 512 bytes (recommended)"
> -	help
> -	 Support correcting up to 8 bitflips per 512-byte block.
> -	 This will use 13 bytes of spare area per 512 bytes of page data.
> -	 This is the recommended mode, as 4-bit mode does not work
> -	 on some OMAP3 revisions, due to a hardware bug.
> -
> -config MTD_NAND_OMAP_BCH4
> -	bool "4 bits / 512 bytes"
> -	help
> -	 Support correcting up to 4 bitflips per 512-byte block.
> -	 This will use 7 bytes of spare area per 512 bytes of page data.
> -	 Note that this mode does not work on some OMAP3 revisions, due to a
> -	 hardware bug. Please check your OMAP datasheet before selecting this
> -	 mode.
> -
> -endchoice
> +	  Some devices have built-in ELM hardware engine, which can be used to
> +	  locate and correct errors when using BCH ECC scheme. This enables the
> +	  driver support for same.
>  
>  if MTD_NAND_OMAP_BCH
>  config BCH_CONST_M

Do you need to to also kill of the Kconfig stuff for BCH_CONST_M and
BCH_CONST_T, which were tied to the MTD_NAND_OMAP_BCH4 and
MTD_NAND_OMAP_BCH8 configs you just removed?

> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 5f6e621..769ff65 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -25,7 +25,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  
> -#include <linux/bch.h>
> +#include <linux/mtd/nand_bch.h>
>  #include <linux/platform_data/elm.h>
>  
>  #include <linux/platform_data/mtd-nand-omap2.h>
> @@ -140,7 +140,6 @@
>  #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
>  
>  #define BADBLOCK_MARKER_LENGTH		2
> -#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
>  
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
> @@ -173,7 +172,6 @@ struct omap_nand_info {
>  	int					buf_len;
>  	struct gpmc_nand_regs		reg;
>  	/* fields specific for BCHx_HW ECC scheme */
> -	struct bch_control             *bch;
>  	bool				is_elm_used;
>  	struct device			*elm_dev;
>  	struct device_node		*of_node;
> @@ -1507,43 +1505,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
>  
>  	return stat;
>  }
> -#endif /* CONFIG_MTD_NAND_OMAP_BCH */
>  
> -#ifdef CONFIG_MTD_NAND_ECC_BCH
> -/**
> - * omap3_correct_data_bch - Decode received data and correct errors
> - * @mtd: MTD device structure
> - * @data: page data
> - * @read_ecc: ecc read from nand flash
> - * @calc_ecc: ecc read from HW ECC registers
> - */
> -static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
> -				  u_char *read_ecc, u_char *calc_ecc)
> -{
> -	int i, count;
> -	/* cannot correct more than 8 errors */
> -	unsigned int errloc[8];
> -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> -						   mtd);
> -
> -	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
> -			   errloc);
> -	if (count > 0) {
> -		/* correct errors */
> -		for (i = 0; i < count; i++) {
> -			/* correct data only, not ecc bytes */
> -			if (errloc[i] < 8*512)
> -				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
> -			pr_debug("corrected bitflip %u\n", errloc[i]);
> -		}
> -	} else if (count < 0) {
> -		pr_err("ecc unrecoverable error\n");
> -	}
> -	return count;
> -}
> -#endif /* CONFIG_MTD_NAND_ECC_BCH */
> -
> -#ifdef CONFIG_MTD_NAND_OMAP_BCH
>  /**
>   * omap_write_page_bch - BCH ecc based write page function for entire page
>   * @mtd:		mtd info structure
> @@ -1660,28 +1622,6 @@ static int is_elm_present(struct omap_nand_info *info,
>  }
>  #endif /* CONFIG_MTD_NAND_ECC_BCH */
>  
> -#ifdef CONFIG_MTD_NAND_ECC_BCH
> -/**
> - * omap3_free_bch - Release BCH ecc resources
> - * @mtd: MTD device structure
> - */
> -static void omap3_free_bch(struct mtd_info *mtd)
> -{
> -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
> -						   mtd);
> -	if (info->bch) {
> -		free_bch(info->bch);
> -		info->bch = NULL;
> -	}
> -}
> -
> -#else
> -
> -static void omap3_free_bch(struct mtd_info *mtd)
> -{
> -}
> -#endif /* CONFIG_MTD_NAND_ECC_BCH */
> -
>  static int omap_nand_probe(struct platform_device *pdev)
>  {
>  	struct omap_nand_info		*info;
> @@ -1714,13 +1654,13 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	info->pdev		= pdev;
>  	info->gpmc_cs		= pdata->cs;
>  	info->reg		= pdata->reg;
> -	info->bch		= NULL;
>  	info->of_node		= pdata->of_node;
>  	mtd			= &info->mtd;
>  	mtd->priv		= &info->nand;
>  	mtd->name		= dev_name(&pdev->dev);
>  	mtd->owner		= THIS_MODULE;
>  	nand_chip		= &info->nand;
> +	nand_chip->ecc.priv	= NULL;
>  	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> @@ -1910,7 +1850,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->ecc.bytes		= 7;
>  		nand_chip->ecc.strength		= 4;
>  		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
> -		nand_chip->ecc.correct		= omap3_correct_data_bch;
> +		info->nand.ecc.correct		= nand_bch_correct_data;
>  		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
>  		/* define ECC layout */
>  		ecclayout->eccbytes		= nand_chip->ecc.bytes *
> @@ -1920,10 +1860,11 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>  							ecclayout->eccbytes;
>  		/* software bch library is used for locating errors */
> -		info->bch = init_bch(nand_chip->ecc.bytes,
> -					nand_chip->ecc.strength,
> -					OMAP_ECC_BCH8_POLYNOMIAL);
> -		if (!info->bch) {
> +		info->nand.ecc.priv		= nand_bch_init(mtd,
> +							info->nand.ecc.size,
> +							info->nand.ecc.bytes,
> +							&info->nand.ecc.layout);

Are you sure nand_bch_init() is a proper drop-in replacement for the
implementation you had based on init_bch()? It looks to me like they at
least use a differnt polynomial value (0x201b vs. 0). Is this a problem
for backwards compatibility?

> +		if (!info->nand.ecc.priv) {
>  			pr_err("nand: error: unable to use s/w BCH library\n");
>  			err = -EINVAL;
>  		}

[...]

> @@ -1985,10 +1926,11 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
>  							ecclayout->eccbytes;
>  		/* software bch library is used for locating errors */
> -		info->bch = init_bch(nand_chip->ecc.bytes,
> -					nand_chip->ecc.strength,
> -					OMAP_ECC_BCH8_POLYNOMIAL);
> -		if (!info->bch) {
> +		info->nand.ecc.priv		= nand_bch_init(mtd,
> +							info->nand.ecc.size,
> +							info->nand.ecc.bytes,
> +							&info->nand.ecc.layout);

Same questions apply.

> +		if (!info->nand.ecc.priv) {
>  			pr_err("nand: error: unable to use s/w BCH library\n");
>  			err = -EINVAL;
>  			goto out_release_mem_region;

[...]

A related question: do we have any current users of this driver that can
provide testing results for this series? Or is this work just tested
with new hardware?

Brian


From computersforpeace at gmail.com  Wed Oct 16 22:29:19 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 19:29:19 -0700
Subject: [PATCH v9 9/9] mtd: nand: omap: updated devm_xx for all
 resource allocation and free calls
In-Reply-To: <1381816197-20477-10-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-10-git-send-email-pekon@ti.com>
Message-ID: <20131017022919.GD23337@ld-irv-0074.broadcom.com>

On Tue, Oct 15, 2013 at 11:19:57AM +0530, Pekon Gupta wrote:
> "Managed Device Resource" or devm_xx calls takes care of automatic freeing
> of the resource in case of:
> - failure during driver probe
> - failure during resource allocation
> - detaching or unloading of driver module (rmmod)
> Reference: Documentation/driver-model/devres.txt
> 
> Though OMAP NAND driver handles freeing of resource allocation in most of
> the cases, but using devm_xx provides more clean and effortless approach
> to handle all such cases.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/omap2.c | 44 ++++++++++++++------------------------------
>  1 file changed, 14 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 769ff65..0ed0d6f 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c

[...]

> @@ -1796,8 +1799,9 @@ static int omap_nand_probe(struct platform_device *pdev)
>  			err = -ENODEV;
>  			goto out_release_mem_region;
>  		}
> -		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
> -					IRQF_SHARED, "gpmc-nand-count", info);
> +		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
> +					omap_nand_irq, IRQF_SHARED,
> +					"gpmc-nand-count", info);
>  		if (err) {
>  			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
>  						info->gpmc_irq_count, err);
> @@ -2010,45 +2014,25 @@ static int omap_nand_probe(struct platform_device *pdev)
>  out_release_mem_region:

Now that you've simplified this error path, you don't need so verbose of
a name (it could just be 'out'), but that's not worth another revision.

>  	if (info->dma)
>  		dma_release_channel(info->dma);
> -	if (info->gpmc_irq_count > 0)
> -		free_irq(info->gpmc_irq_count, info);
> -	if (info->gpmc_irq_fifo > 0)
> -		free_irq(info->gpmc_irq_fifo, info);
> -	release_mem_region(info->phys_base, info->mem_size);
> -out_free_info:
>  	if (info->nand.ecc.priv) {
>  		nand_bch_free(info->nand.ecc.priv);
>  		info->nand.ecc.priv = NULL;
>  	}
> -	kfree(info);
> -
>  	return err;
>  }

[...]

This patch version looks much better. Thanks for the rewrite.

Brian


From computersforpeace at gmail.com  Wed Oct 16 22:35:36 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 16 Oct 2013 19:35:36 -0700
Subject: [PATCH v9 0/9] mtd:nand:omap2: clean-up of supported ECC schemes
In-Reply-To: <1381816197-20477-1-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
Message-ID: <20131017023536.GE23337@ld-irv-0074.broadcom.com>

Hi,

On Tue, Oct 15, 2013 at 11:19:48AM +0530, Pekon Gupta wrote:
> 
> *changes v8 -> v9*
> [PATCH 1/9] <no update from [PATCH v8 1/6]>
> [PATCH 2/9] <only commit log updated from [PATCH v8 2/6]>
>  As per feedbacks from Brian Norris <computersforpeace at gmail.com> previous
>  revision [PATCH v8 3/6] and [PATCH 4/6] are split into following sub-patches:
> - [PATCH 3/9] <new> replaces local reference with generic names (mtd, nand_chip)
> - [PATCH 4/9] <new> enables auto-detection of bus-width
> - [PATCH 5/9] <new> removes omap3_init_bch: populates ecc-scheme data
> - [PATCH 6/9] <new> removes omap3_init_bch_tail: populates ecc-layout
> - [PATCH 7/9] <new> replaces lib/bch.c with nand_bch.c wrapper
> [PATCH 8/9] <no update same as [PATCH v8 5/6]
> [PATCH 9/9] removed devm_free_xx functions

[...]

I had a few comments on patches 4 and 7, but everything else is looking
a lot better.

Thanks,
Brian


From pekon at ti.com  Thu Oct 17 00:42:23 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 17 Oct 2013 04:42:23 +0000
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
 <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>

Hi Brian,

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On Tue, Oct 15, 2013 at 11:19:52AM +0530, Pekon Gupta wrote:
> > Autodetection of NAND device bus-width was added in generic NAND
> driver as
[...]
> > @@ -1904,6 +1903,21 @@ static int omap_nand_probe(struct
> platform_device *pdev)
> >  		nand_chip->chip_delay = 50;
> >  	}
> >
> > +	/* scan for NAND device connected to chip controller */
> > +	if (nand_scan_ident(mtd, 1, NULL)) {
> > +		err = -ENXIO;
> > +		goto out_release_mem_region;
> > +	}
> > +	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
> > +			(pdata->devsize & NAND_BUSWIDTH_16)) {
> > +		pr_err("%s: detected %s device but driver configured for
> %s\n",
> > +			DRIVER_NAME,
> > +			(nand_chip->options & NAND_BUSWIDTH_16) ?
> "x16" : "x8",
> > +			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" :
> "x8");
> 
> I'm not sure on the policy choice here; if you're using BUSWIDTH_AUTO,
> do you even want to try to configure the buswidth by platform data?
> You're not really getting the full use out of NAND_BUSWIDTH_AUTO because
> the platform data has to guess the same buswidth that nand_base.c
> determines. This is worse than the previous behavior, in which you would
> try both buswidths if the specified type failed.
> 
> IOW, what are you trying to achieve with auto-buswidth? Automatic
> determination of the buswidth or just automatic validation? What do you
> achieve with platform data's selection of buswidth? Specification of the
> buswidth or just a hint? Do the goals conflict? Perhaps you can just
> warn, and not error out if the two selections don't match? Or maybe you
> really wanted to replace the platform data selection mechanism entirely
> with auto-buswidth?
> 
This is 'automatic validation' of value set in DT binding "nand-bus-width"
So this approach is other way round, where controller is configured
based on DT binding "nand-bus-width" and then it checks whether
device actual buswidth matches DT binding value or not.

- GPMC controller is pre-configured to support "x8" or "x16" device based
   on DT binding "nand-bus-width".
   Reference: $LINUX/arch/arm/mach-omap2/gpmc.c
  @@gpmc_probe_nand_child()
	val = of_get_nand_bus_width(child);

- But, bus-width of NAND device is only known during NAND driver
   Probe in nand_scan_ident().

Going forward when all NAND devices are compliant to ONFI,
then we can deprecate "nand-bus-width".


with regards, pekon


From ezequiel.garcia at free-electrons.com  Thu Oct 17 05:24:57 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 17 Oct 2013 06:24:57 -0300
Subject: [PATCH] mtd: nand: pxa3xx: Fix registered MTD name
Message-ID: <1382001897-2709-1-git-send-email-ezequiel.garcia@free-electrons.com>

In a recent commit:

  commit f455578dd961087a5cf94730d9f6489bb1d355f0
  Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
  Date:   Mon Aug 12 14:14:53 2013 -0300

  mtd: nand: pxa3xx: Remove hardcoded mtd name

  There's no advantage in using a hardcoded name for the mtd device.
  Instead use the provided by the platform_device.

The MTD name was changed to use the one provided by the platform_device.
However, this can be problematic as some users want to set partitions
using the kernel parameter 'mtdpart', where the name is needed.

For that reason, using a simpler and easier to remember name such
as 'pxa3xx-nand' is certainly a better choice.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index aa75adf..6ec3810 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -46,6 +46,8 @@
  */
 #define INIT_BUFFER_SIZE	256
 
+#define DRIVER_NAME		"pxa3xx-nand"
+
 /* registers and bit definitions */
 #define NDCR		(0x00) /* Control register */
 #define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */
@@ -1339,7 +1341,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 	for (cs = 0; cs < pdata->num_cs; cs++) {
 		struct mtd_info *mtd = info->host[cs]->mtd;
 
-		mtd->name = pdev->name;
+		mtd->name = DRIVER_NAME;
 		info->cs = cs;
 		ret = pxa3xx_nand_scan(mtd);
 		if (ret) {
@@ -1425,7 +1427,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
 
 static struct platform_driver pxa3xx_nand_driver = {
 	.driver = {
-		.name	= "pxa3xx-nand",
+		.name	= DRIVER_NAME,
 		.of_match_table = pxa3xx_nand_dt_ids,
 	},
 	.probe		= pxa3xx_nand_probe,
-- 
1.8.1.5



From pekon at ti.com  Thu Oct 17 06:14:40 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 17 Oct 2013 10:14:40 +0000
Subject: [PATCH v9 7/9] mtd: nand: omap: use drivers/mtd/nand/nand_bch.c
 wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <20131017022237.GC23337@ld-irv-0074.broadcom.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-8-git-send-email-pekon@ti.com>
 <20131017022237.GC23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA27C63@DBDE04.ent.ti.com>

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On Tue, Oct 15, 2013 at 11:19:55AM +0530, Pekon Gupta wrote:
[snip]

> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> > index d885298..5836039 100644
> > --- a/drivers/mtd/nand/Kconfig
> > +++ b/drivers/mtd/nand/Kconfig
> > @@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
> >
> >  config MTD_NAND_OMAP_BCH
> >  	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
> > -	tristate "Enable support for hardware BCH error correction"
> > +	tristate "Support hardware based BCH error correction"
> >  	default n
> >  	select BCH
> > -	select BCH_CONST_PARAMS
> 
> Do you know what will happen now if someone configures
> BCH_CONST_PARAMS?
> Would this cause problems?
> 
As per comments in lib/bch.c 
--------------------------- 
* Option CONFIG_BCH_CONST_PARAMS can be used to force fixed values of
 * parameters m and t; thus allowing extra compiler optimizations and providing
 * better (up to 2x) encoding performance. Using this option makes sense when
 * (m,t) are fixed and known in advance, e.g. when using BCH error correction
 * on a particular NAND flash device.
---------------------------
'BCH_CONST_PARAMS' is required for optimization when BCH algorithm
is fixed. But in omap-nand case selection of type of BCH algorithm
(BCH4 or BCH8) comes from DT binding "ti,nand-ecc-opts".

If enabled (CONFIG_BCH_CONST_PARAMS) will optimize lib/bch.c
for BCH8 algorithm by default, so 
CASE: if BCH8 is selected by DT, then no issues
CASE: if BCH4 is selected  then nand_bch_init() fails with following error
+ if (!info->nand.ecc.priv) {
		pr_err("nand: error: unable to use s/w BCH library\n");
		err = -EINVAL;
		goto out_release_mem_region;
}

[snip] 

> >  if MTD_NAND_OMAP_BCH
> >  config BCH_CONST_M
> 
> Do you need to to also kill of the Kconfig stuff for BCH_CONST_M and
> BCH_CONST_T, which were tied to the MTD_NAND_OMAP_BCH4 and
> MTD_NAND_OMAP_BCH8 configs you just removed?
> 
Thanks, good catch. I dint really notice.
So, the driver is now updated to separate out two flavours of BCHx scheme.
(a) OMAP_ECC_BCHx_CODE_HW: which uses ELM hardware
(b) OMAP_ECC_BCHx_CODE_HW_DETECTION_SW: which uses lib/bch.c
These BCH_CONST_M and BCH_CONST_T now belongs to (b) family only.
-  if MTD_NAND_OMAP_BCH
+ if MTD_NAND_ECC_BCH
       config BCH_CONST_M
(I'll update that)..


> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
[snip]
> > -		info->bch = init_bch(nand_chip->ecc.bytes,
> > -					nand_chip->ecc.strength,
> > -					OMAP_ECC_BCH8_POLYNOMIAL);
> > -		if (!info->bch) {
> > +		info->nand.ecc.priv	= nand_bch_init(mtd,
> > +						info->nand.ecc.size,
> > +						info->nand.ecc.bytes,
> > +						&info->nand.ecc.layout);
> 
> Are you sure nand_bch_init() is a proper drop-in replacement for the
> implementation you had based on init_bch()? It looks to me like they at
> least use a differnt polynomial value (0x201b vs. 0). Is this a problem
> for backwards compatibility?
> 
It's not the polynomial value = 0. Rather 0x201b is selected in both cases
Refer below code.
---------------
When init_bch(m,t, 0) is called from nand_bch_init() then,
lib/bch.c @@ init_bch(int m, int t, unsigned int prim_poly)
(a)	/* default primitive polynomials */
	static const unsigned int prim_poly_tab[] = {
		0x25, 0x43, 0x83, 0x11d, 0x211, 0x409, 0x805, 0x1053, 0x201b,
		0x402b, 0x8003,
	};
(b)	/* select a primitive polynomial for generating GF(2^m) */
	if (prim_poly == 0)
		prim_poly = prim_poly_tab[m-min_m];
(c) And, const int min_m = 5;

So, for BCH8 m=13, min_m=5; So 
prim_poly = prim_poly_tab[13-5] = prim_poly_tab[8] = 0x201b
---------------

Hence, there is no change in polynomial, it's just that instead of
hard-coding the value, polynomial selection depends on 'm' and 't'.



> [...]
> 
> A related question: do we have any current users of this driver that can
> provide testing results for this series? Or is this work just tested
> with new hardware?
> 
Got a tested-by: jp.francois at cynove.com for BCH4
But that was in May,2013 :-)
http://lists.infradead.org/pipermail/linux-mtd/2013-May/047065.html


with regards, pekon


From sourav.poddar at ti.com  Thu Oct 17 08:24:53 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 17 Oct 2013 17:54:53 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
References: <52566ACC.1080100@ti.com> <20131010101410.GG21581@sirena.org.uk>
 <52568AA3.9080203@ti.com> <20131011100839.GA21581@sirena.org.uk>
 <525CDB77.4040201@ti.com> <20131015111647.GX2443@sirena.org.uk>
 <525D2BB3.4020705@ti.com> <20131015124656.GM2443@sirena.org.uk>
 <525D41E2.30206@ti.com> <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
Message-ID: <525FD715.50703@ti.com>

Hi All,
On Wednesday 16 October 2013 12:03 AM, Gupta, Pekon wrote:
>> From: Trent Piepho
>> Are there any numbers to show if memory mapped read support is a
>> benefit in Linux?  There is some question as to whether it's useful at
>> all or not.
>>
>> If it is, I think low latency for small reads is probably one of the
>> only advantages.  To do that, you aren't going to want to deal with
>> device PM for every single read.  It would make more sense to turn the
>> hardware on when the MTD device is opened and leave it on until
>> closed.
>>
> +1
>
> Therefore early suggestions were to make 'MM_MODE' as default
> (if device enables it via DT). This means:
> (1) switch to 'SPI_MODE' _only_ when required for commands like
>   mtd_erase, etc. and switch back to 'MM_MODE' when done.
> (2) And keep your controller clocks on.
>
> This would ensure that you do minimum config-switching when using
> MM_MODE. And would thus achieve low latency, and no driver intervention.
>
> Yes, real thruput numbers would help clear the picture here ..
>
> with regards, pekon
I did some throughput measurement to get some number on the
read side. Here are my observations:

Case1:
--------
  Using SPI framework.

   Setup:
     Here, the actual memcpy is done in the spi controller, and flash
     communicates to the qspi controller to do the memcpy using the
     SPI framework. This is what is propsed in the $subject patch.

   Measurement method:
     used jiffies_to_msecs  at the beginning and at the end of the 
mtd_read api
    and calculated the difference.

   Result:
      Tried a transfer of 32KB, which takes around 20 ms of time to read.


Case2:
--------
  Bypassing SPI framework.

   Setup:
     Here, the actual memcpy is done in the mtd read api itself, by 
getting the
     memmap address from the spi controller.

   Measurement method:
     used jiffies_to_msecs  before and after memcpy and calculated the 
difference.

   Result:
      Tried a transfer of 32KB, which takes around 10 ms of time to read.

So, time reduced almost to half while bypassing the SPI framework.










From broonie at kernel.org  Thu Oct 17 08:38:50 2013
From: broonie at kernel.org (Mark Brown)
Date: Thu, 17 Oct 2013 13:38:50 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <525FD715.50703@ti.com>
References: <20131011100839.GA21581@sirena.org.uk> <525CDB77.4040201@ti.com>
 <20131015111647.GX2443@sirena.org.uk> <525D2BB3.4020705@ti.com>
 <20131015124656.GM2443@sirena.org.uk> <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com>
Message-ID: <20131017123850.GN2443@sirena.org.uk>

On Thu, Oct 17, 2013 at 05:54:53PM +0530, Sourav Poddar wrote:

>   Setup:
>     Here, the actual memcpy is done in the spi controller, and flash
>     communicates to the qspi controller to do the memcpy using the
>     SPI framework. This is what is propsed in the $subject patch.

>   Setup:
>     Here, the actual memcpy is done in the mtd read api itself, by
> getting the
>     memmap address from the spi controller.

> So, time reduced almost to half while bypassing the SPI framework.

The interesting case for benchmarking here is more a comparison between
normal DMA driven transfers and the memcpy().  Some consideration of the
CPU load would also be interesting here, if the SoC is waiting for the
flash then it's probably useful if it can make progress on other things.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131017/cfa7b09b/attachment-0001.sig>

From jp.francois at cynove.com  Thu Oct 17 08:42:17 2013
From: jp.francois at cynove.com (jean-philippe francois)
Date: Thu, 17 Oct 2013 14:42:17 +0200
Subject: [PATCH v9 7/9] mtd: nand: omap: use drivers/mtd/nand/nand_bch.c
 wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA27C63@DBDE04.ent.ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-8-git-send-email-pekon@ti.com>
 <20131017022237.GC23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27C63@DBDE04.ent.ti.com>
Message-ID: <CAGGh5h3PU0PR1SMa_aWUvPxccWS9A+Rxp7pm0U8u6fBnPcOvjw@mail.gmail.com>

2013/10/17 Gupta, Pekon <pekon at ti.com>:
>> From: Brian Norris [mailto:computersforpeace at gmail.com]
>> > On Tue, Oct 15, 2013 at 11:19:55AM +0530, Pekon Gupta wrote:
> [snip]
>
>> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
>> > index d885298..5836039 100644
>> > --- a/drivers/mtd/nand/Kconfig
>> > +++ b/drivers/mtd/nand/Kconfig
>> > @@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
>> >
>> >  config MTD_NAND_OMAP_BCH
>> >     depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
>> > -   tristate "Enable support for hardware BCH error correction"
>> > +   tristate "Support hardware based BCH error correction"
>> >     default n
>> >     select BCH
>> > -   select BCH_CONST_PARAMS
>>
>> Do you know what will happen now if someone configures
>> BCH_CONST_PARAMS?
>> Would this cause problems?
>>
> As per comments in lib/bch.c
> ---------------------------
> * Option CONFIG_BCH_CONST_PARAMS can be used to force fixed values of
>  * parameters m and t; thus allowing extra compiler optimizations and providing
>  * better (up to 2x) encoding performance. Using this option makes sense when
>  * (m,t) are fixed and known in advance, e.g. when using BCH error correction
>  * on a particular NAND flash device.
> ---------------------------
> 'BCH_CONST_PARAMS' is required for optimization when BCH algorithm
> is fixed. But in omap-nand case selection of type of BCH algorithm
> (BCH4 or BCH8) comes from DT binding "ti,nand-ecc-opts".
>
> If enabled (CONFIG_BCH_CONST_PARAMS) will optimize lib/bch.c
> for BCH8 algorithm by default, so
> CASE: if BCH8 is selected by DT, then no issues
> CASE: if BCH4 is selected  then nand_bch_init() fails with following error
> + if (!info->nand.ecc.priv) {
>                 pr_err("nand: error: unable to use s/w BCH library\n");
>                 err = -EINVAL;
>                 goto out_release_mem_region;
> }
>
> [snip]
>
>> >  if MTD_NAND_OMAP_BCH
>> >  config BCH_CONST_M
>>
>> Do you need to to also kill of the Kconfig stuff for BCH_CONST_M and
>> BCH_CONST_T, which were tied to the MTD_NAND_OMAP_BCH4 and
>> MTD_NAND_OMAP_BCH8 configs you just removed?
>>
> Thanks, good catch. I dint really notice.
> So, the driver is now updated to separate out two flavours of BCHx scheme.
> (a) OMAP_ECC_BCHx_CODE_HW: which uses ELM hardware
> (b) OMAP_ECC_BCHx_CODE_HW_DETECTION_SW: which uses lib/bch.c
> These BCH_CONST_M and BCH_CONST_T now belongs to (b) family only.
> -  if MTD_NAND_OMAP_BCH
> + if MTD_NAND_ECC_BCH
>        config BCH_CONST_M
> (I'll update that)..
>
>
>> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> [snip]
>> > -           info->bch = init_bch(nand_chip->ecc.bytes,
>> > -                                   nand_chip->ecc.strength,
>> > -                                   OMAP_ECC_BCH8_POLYNOMIAL);
>> > -           if (!info->bch) {
>> > +           info->nand.ecc.priv     = nand_bch_init(mtd,
>> > +                                           info->nand.ecc.size,
>> > +                                           info->nand.ecc.bytes,
>> > +                                           &info->nand.ecc.layout);
>>
>> Are you sure nand_bch_init() is a proper drop-in replacement for the
>> implementation you had based on init_bch()? It looks to me like they at
>> least use a differnt polynomial value (0x201b vs. 0). Is this a problem
>> for backwards compatibility?
>>
> It's not the polynomial value = 0. Rather 0x201b is selected in both cases
> Refer below code.
> ---------------
> When init_bch(m,t, 0) is called from nand_bch_init() then,
> lib/bch.c @@ init_bch(int m, int t, unsigned int prim_poly)
> (a)     /* default primitive polynomials */
>         static const unsigned int prim_poly_tab[] = {
>                 0x25, 0x43, 0x83, 0x11d, 0x211, 0x409, 0x805, 0x1053, 0x201b,
>                 0x402b, 0x8003,
>         };
> (b)     /* select a primitive polynomial for generating GF(2^m) */
>         if (prim_poly == 0)
>                 prim_poly = prim_poly_tab[m-min_m];
> (c) And, const int min_m = 5;
>
> So, for BCH8 m=13, min_m=5; So
> prim_poly = prim_poly_tab[13-5] = prim_poly_tab[8] = 0x201b
> ---------------
>
> Hence, there is no change in polynomial, it's just that instead of
> hard-coding the value, polynomial selection depends on 'm' and 't'.
>
>
>
>> [...]
>>
>> A related question: do we have any current users of this driver that can
>> provide testing results for this series? Or is this work just tested
>> with new hardware?
>>
> Got a tested-by: jp.francois at cynove.com for BCH4
> But that was in May,2013 :-)
> http://lists.infradead.org/pipermail/linux-mtd/2013-May/047065.html
>
>
> with regards, pekon

Yes, but I am currently stuck on 3.10, and I need to migrate my out of tree
board file to a device tree, and I currently have no bandwidth for this, so I
won't be able to test the whole serie, but may be some parts are
testable independently ?

I will take a look and tell you.

Regards,
Jean-Philippe Fran?ois


From pekon at ti.com  Thu Oct 17 09:03:26 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 17 Oct 2013 13:03:26 +0000
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131017123850.GN2443@sirena.org.uk>
References: <20131011100839.GA21581@sirena.org.uk> <525CDB77.4040201@ti.com>
 <20131015111647.GX2443@sirena.org.uk> <525D2BB3.4020705@ti.com>
 <20131015124656.GM2443@sirena.org.uk> <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>

Hi Mark,

> From: Mark Brown [mailto:broonie at kernel.org]
> > On Thu, Oct 17, 2013 at 05:54:53PM +0530, Sourav Poddar wrote:
> >   Setup:
> >     Here, the actual memcpy is done in the spi controller, and flash
> >     communicates to the qspi controller to do the memcpy using the
> >     SPI framework. This is what is propsed in the $subject patch.
> 
> >   Setup:
> >     Here, the actual memcpy is done in the mtd read api itself, by
> > getting the
> >     memmap address from the spi controller.
> 
> > So, time reduced almost to half while bypassing the SPI framework.
> 
> The interesting case for benchmarking here is more a comparison between
> normal DMA driven transfers and the memcpy().  Some consideration of the
> CPU load would also be interesting here, if the SoC is waiting for the
> flash then it's probably useful if it can make progress on other things.
> 
So in this CASE-2:  SPI framework is bypassed: mtd_read() becomes
mtd_read() {
	if (flash->mmap_mode)
		if (dma_available)
			read_via_dma(destination, source, length);
		else
			memcpy(destination, source, length);
	else
		/* use spi frame-work by default */
}

Are you looking for comparison between  read_via_dma() v/s memcpy() ?

If yes, then unfortunately we are bit constrained because our controller
does not support DMA. So, we have to depend on CPU based memcpy()
only. However, use of DMA can be added as an independent patch on
top of this CASE-2 patch.

So will the base patch for CASE-2  (with SPI framework is bypassed) help ?


with regards, pekon


From computersforpeace at gmail.com  Thu Oct 17 14:30:16 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 17 Oct 2013 11:30:16 -0700
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
 <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>
Message-ID: <20131017183016.GG23337@ld-irv-0074.broadcom.com>

On Thu, Oct 17, 2013 at 04:42:23AM +0000, Pekon Gupta wrote:
> > From: Brian Norris [mailto:computersforpeace at gmail.com]
> > > On Tue, Oct 15, 2013 at 11:19:52AM +0530, Pekon Gupta wrote:
> > > Autodetection of NAND device bus-width was added in generic NAND
> > driver as
> [...]
> > > @@ -1904,6 +1903,21 @@ static int omap_nand_probe(struct
> > platform_device *pdev)
> > >  		nand_chip->chip_delay = 50;
> > >  	}
> > >
> > > +	/* scan for NAND device connected to chip controller */
> > > +	if (nand_scan_ident(mtd, 1, NULL)) {
> > > +		err = -ENXIO;
> > > +		goto out_release_mem_region;
> > > +	}
> > > +	if ((nand_chip->options & NAND_BUSWIDTH_16) !=
> > > +			(pdata->devsize & NAND_BUSWIDTH_16)) {
> > > +		pr_err("%s: detected %s device but driver configured for
> > %s\n",
> > > +			DRIVER_NAME,
> > > +			(nand_chip->options & NAND_BUSWIDTH_16) ?
> > "x16" : "x8",
> > > +			(pdata->devsize & NAND_BUSWIDTH_16) ? "x16" :
> > "x8");
> > 
> > I'm not sure on the policy choice here; if you're using BUSWIDTH_AUTO,
> > do you even want to try to configure the buswidth by platform data?
> > You're not really getting the full use out of NAND_BUSWIDTH_AUTO because
> > the platform data has to guess the same buswidth that nand_base.c
> > determines. This is worse than the previous behavior, in which you would
> > try both buswidths if the specified type failed.
> > 
> > IOW, what are you trying to achieve with auto-buswidth? Automatic
> > determination of the buswidth or just automatic validation? What do you
> > achieve with platform data's selection of buswidth? Specification of the
> > buswidth or just a hint? Do the goals conflict? Perhaps you can just
> > warn, and not error out if the two selections don't match? Or maybe you
> > really wanted to replace the platform data selection mechanism entirely
> > with auto-buswidth?
> > 
> This is 'automatic validation' of value set in DT binding "nand-bus-width"

You mean you intend for the patched driver to simply validate, not
configure the buswidth?

> So this approach is other way round, where controller is configured
> based on DT binding "nand-bus-width" and then it checks whether
> device actual buswidth matches DT binding value or not.

If this is the case, then you really don't want to use
NAND_BUSWIDTH_AUTO. The default nand_base.c just *validates* the
pre-selected buswidth and exits with an error, in much the same way that
you're doing here (you're just duplicating the functionality).
NAND_BUSWIDTH_AUTO is useful if you want to turn control of the buswidth
configuration entirely over to nand_base.c.

> - GPMC controller is pre-configured to support "x8" or "x16" device based
>    on DT binding "nand-bus-width".
>    Reference: $LINUX/arch/arm/mach-omap2/gpmc.c
>   @@gpmc_probe_nand_child()
> 	val = of_get_nand_bus_width(child);
> 
> - But, bus-width of NAND device is only known during NAND driver
>    Probe in nand_scan_ident().
> 
> Going forward when all NAND devices are compliant to ONFI,
> then we can deprecate "nand-bus-width".

Buswidth auto-detection is not actually restricted to ONFI. nand_base.c
has (corretly, AFAIK) been detecting buswidths for a long time, using
some form of ID decode detection. But it was just that: detection. It
did not actually configure the buswidth, since it left that
responsibility to the low-level driver to get right.

Another thing to consider: I think this current patch is a regression
from previous behavior. Previously, you would run nand_scan_ident()
twice if the first one failed; once with the platform-configured
buswidth and once with the opposite. But now, you only run
nand_scan_ident() once, and then you quit if it detects differently than
you expected.

My opinion: the platform- and device-tree-provided buswidth is
unnecessary; it was previouisly only a suggestion which your driver
would readily discard, and it isn't really needed now. You can probably
get by with just NAND_BUSWIDTH_AUTO and (at most) a warning if the
auto-configured buswidth is different than the platform specified.

But the real point: you need to clearly communicate what you are
choosing in this patch. Either you want to

 (1) strictly follow the buswidth provided by the platform or

 (2) use the nand_base.c BUSWIDTH_AUTO automatic configuration.

Trying to mix both (as your patch currently does) just makes everything
worse.

Brian


From pekon at ti.com  Thu Oct 17 17:00:27 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 17 Oct 2013 21:00:27 +0000
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <20131017183016.GG23337@ld-irv-0074.broadcom.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
 <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>
 <20131017183016.GG23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA280A4@DBDE04.ent.ti.com>

Hi Brain,

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On Thu, Oct 17, 2013 at 04:42:23AM +0000, Pekon Gupta wrote:
> > > From: Brian Norris [mailto:computersforpeace at gmail.com]
> > > > On Tue, Oct 15, 2013 at 11:19:52AM +0530, Pekon Gupta wrote:
[snip]
> > So this approach is other way round, where controller is configured
> > based on DT binding "nand-bus-width" and then it checks whether
> > device actual buswidth matches DT binding value or not.
> 
> If this is the case, then you really don't want to use
> NAND_BUSWIDTH_AUTO. The default nand_base.c just *validates* the
> pre-selected buswidth and exits with an error, in much the same way that
> you're doing here (you're just duplicating the functionality).
> NAND_BUSWIDTH_AUTO is useful if you want to turn control of the
> buswidth
> configuration entirely over to nand_base.c.
> 
> > - GPMC controller is pre-configured to support "x8" or "x16" device based
> >    on DT binding "nand-bus-width".
> >    Reference: $LINUX/arch/arm/mach-omap2/gpmc.c
> >   @@gpmc_probe_nand_child()
> > 	val = of_get_nand_bus_width(child);
> >
> > - But, bus-width of NAND device is only known during NAND driver
> >    Probe in nand_scan_ident().
> >
> > Going forward when all NAND devices are compliant to ONFI,
> > then we can deprecate "nand-bus-width".
> 
> Buswidth auto-detection is not actually restricted to ONFI. nand_base.c
> has (corretly, AFAIK) been detecting buswidths for a long time, using
> some form of ID decode detection. But it was just that: detection. It
> did not actually configure the buswidth, since it left that
> responsibility to the low-level driver to get right.
> 
> Another thing to consider: I think this current patch is a regression
> from previous behavior. Previously, you would run nand_scan_ident()
> twice if the first one failed; once with the platform-configured
> buswidth and once with the opposite. But now, you only run
> nand_scan_ident() once, and then you quit if it detects differently than
> you expected.
> 
Actually having nand_scan_ident() called again if first time it fails, is 
_not_ the right way, it was a quick-fix work-around.
It should not have been approved..


> My opinion: the platform- and device-tree-provided buswidth is
> unnecessary; it was previouisly only a suggestion which your driver
> would readily discard, and it isn't really needed now. You can probably
> get by with just NAND_BUSWIDTH_AUTO and (at most) a warning if the
> auto-configured buswidth is different than the platform specified.
> 
> But the real point: you need to clearly communicate what you are
> choosing in this patch. Either you want to
> 
>  (1) strictly follow the buswidth provided by the platform or
> 
>  (2) use the nand_base.c BUSWIDTH_AUTO automatic configuration.
> 
Ideally, I would like to go with (2), but that would need other changes
in-order to re-configure GPMC with newly parsed ONFI data, which
can be a separate patch-set.

Thus, I would drop this patch for now. And go with (1), with following
updates in  omap_nand_probe().

(a) perform nand_scan_ident() in "x8" mode, so that ONFI params are
    read and device-info (chip->writesize, chip->oobsize) are populated.

(b) Then switch to "x8" or "x16" mode based on "nand-bus-width"
    as passed from GPMC driver to NAND driver via platform-data.
   And re-populate mtd->byte, mtd-read_buf, mtd->write_buf.


with regards, pekon


From pekon at ti.com  Thu Oct 17 17:26:09 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 17 Oct 2013 21:26:09 +0000
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA280A4@DBDE04.ent.ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
 <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>
 <20131017183016.GG23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA280A4@DBDE04.ent.ti.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA280EA@DBDE04.ent.ti.com>

> 
> Hi Brain,
> 
Oop sorry .. 
s/Brain/Brian

synonymous though :-)


with regards, pekon


From computersforpeace at gmail.com  Thu Oct 17 17:43:49 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 17 Oct 2013 14:43:49 -0700
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA280A4@DBDE04.ent.ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
 <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>
 <20131017183016.GG23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA280A4@DBDE04.ent.ti.com>
Message-ID: <20131017214349.GH23337@ld-irv-0074.broadcom.com>

On Thu, Oct 17, 2013 at 09:00:27PM +0000, Pekon Gupta wrote:
> > From: Brian Norris [mailto:computersforpeace at gmail.com]
> > > On Thu, Oct 17, 2013 at 04:42:23AM +0000, Pekon Gupta wrote:
> > > > From: Brian Norris [mailto:computersforpeace at gmail.com]
> > > > > On Tue, Oct 15, 2013 at 11:19:52AM +0530, Pekon Gupta wrote:
> [snip]
> > > So this approach is other way round, where controller is configured
> > > based on DT binding "nand-bus-width" and then it checks whether
> > > device actual buswidth matches DT binding value or not.
> > 
> > If this is the case, then you really don't want to use
> > NAND_BUSWIDTH_AUTO. The default nand_base.c just *validates* the
> > pre-selected buswidth and exits with an error, in much the same way that
> > you're doing here (you're just duplicating the functionality).
> > NAND_BUSWIDTH_AUTO is useful if you want to turn control of the
> > buswidth
> > configuration entirely over to nand_base.c.
> > 
> > > - GPMC controller is pre-configured to support "x8" or "x16" device based
> > >    on DT binding "nand-bus-width".
> > >    Reference: $LINUX/arch/arm/mach-omap2/gpmc.c
> > >   @@gpmc_probe_nand_child()
> > > 	val = of_get_nand_bus_width(child);
> > >
> > > - But, bus-width of NAND device is only known during NAND driver
> > >    Probe in nand_scan_ident().
> > >
> > > Going forward when all NAND devices are compliant to ONFI,
> > > then we can deprecate "nand-bus-width".
> > 
> > Buswidth auto-detection is not actually restricted to ONFI. nand_base.c
> > has (corretly, AFAIK) been detecting buswidths for a long time, using
> > some form of ID decode detection. But it was just that: detection. It
> > did not actually configure the buswidth, since it left that
> > responsibility to the low-level driver to get right.
> > 
> > Another thing to consider: I think this current patch is a regression
> > from previous behavior. Previously, you would run nand_scan_ident()
> > twice if the first one failed; once with the platform-configured
> > buswidth and once with the opposite. But now, you only run
> > nand_scan_ident() once, and then you quit if it detects differently than
> > you expected.
> > 
> Actually having nand_scan_ident() called again if first time it fails, is 
> _not_ the right way, it was a quick-fix work-around.
> It should not have been approved..

OK, fair enough. I agree.

> > My opinion: the platform- and device-tree-provided buswidth is
> > unnecessary; it was previouisly only a suggestion which your driver
> > would readily discard, and it isn't really needed now. You can probably
> > get by with just NAND_BUSWIDTH_AUTO and (at most) a warning if the
> > auto-configured buswidth is different than the platform specified.
> > 
> > But the real point: you need to clearly communicate what you are
> > choosing in this patch. Either you want to
> > 
> >  (1) strictly follow the buswidth provided by the platform or
> > 
> >  (2) use the nand_base.c BUSWIDTH_AUTO automatic configuration.
> > 
> Ideally, I would like to go with (2), but that would need other changes
> in-order to re-configure GPMC with newly parsed ONFI data, which
> can be a separate patch-set.

What exactly needs changed to support this? It looks like this omap2
NAND driver doesn't make assumptions about 8-bit vs. 16-bit until after
nand_scan_ident(). But maybe there is something I missed.

> Thus, I would drop this patch for now. And go with (1),

OK, but to drop this patch entirely would still not be (1); it would
still leave the possibility of calling nand_scan_ident() twice, and it
puts you in a middle ground between (1) and (2). That's fine if it works
for you, but I just want to acknowledge that now: this driver requires
changes to become either (1) or (2).

Does your series need a rebase if we're removing this patch? Or you're
rewriting/simplifying it to the following two points? (Perhaps it's
best to separate this portion to its own patch (set) and discussion,
since it is independent of your ECC rewrite.)

> with following
> updates in  omap_nand_probe().
> 
> (a) perform nand_scan_ident() in "x8" mode, so that ONFI params are
>     read and device-info (chip->writesize, chip->oobsize) are populated.

OK.

> (b) Then switch to "x8" or "x16" mode based on "nand-bus-width"
>     as passed from GPMC driver to NAND driver via platform-data.
>    And re-populate mtd->byte, mtd-read_buf, mtd->write_buf.

I'm not sure if switching buswidth after nand_scan_ident() is really
supported, but I'll hold off until I see the code you're proposing.

Brian


From ezequiel.garcia at free-electrons.com  Thu Oct 17 18:27:03 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 17 Oct 2013 19:27:03 -0300
Subject: [PATCH 05/21] mtd: nand: pxa3xx: Add driver-specific ECC BCH
 support
In-Reply-To: <20131005002713.GA23337@ld-irv-0074.broadcom.com>
References: <1379606505-2529-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1379606505-2529-6-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131003002440.GY23337@ld-irv-0074.broadcom.com>
 <20131004194923.GC20476@localhost>
 <20131005002713.GA23337@ld-irv-0074.broadcom.com>
Message-ID: <20131017222702.GA2485@localhost>

Brian,

On Fri, Oct 04, 2013 at 05:27:13PM -0700, Brian Norris wrote:
[..]
> 
> Speaking of that: how do you deal with bad block markers, if your data
> is actually placed in what is traditionally the "spare area"?
> 

We currently don't deal with this :(

I'll be sending a v2 soon to address many of the issues you brought
and to re-work the ECC mode 'choice' to be safer.

I'll post the open issues in the v2 cover-letter, and this factory bad block
thing will be among them.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From broonie at kernel.org  Thu Oct 17 19:42:30 2013
From: broonie at kernel.org (Mark Brown)
Date: Fri, 18 Oct 2013 00:42:30 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
References: <20131015111647.GX2443@sirena.org.uk> <525D2BB3.4020705@ti.com>
 <20131015124656.GM2443@sirena.org.uk> <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
Message-ID: <20131017234230.GZ2443@sirena.org.uk>

On Thu, Oct 17, 2013 at 01:03:26PM +0000, Gupta, Pekon wrote:

> mtd_read() {
> 	if (flash->mmap_mode)
> 		if (dma_available)
> 			read_via_dma(destination, source, length);
> 		else
> 			memcpy(destination, source, length);
> 	else
> 		/* use spi frame-work by default */
> }

> Are you looking for comparison between  read_via_dma() v/s memcpy() ?

No, I'm looking for a comparison of normal SPI mode (which I'd have
expected to DMA) and the memcpy() mode.

> If yes, then unfortunately we are bit constrained because our controller
> does not support DMA. So, we have to depend on CPU based memcpy()
> only. However, use of DMA can be added as an independent patch on
> top of this CASE-2 patch.

However if the controller can't DMA at all then that's not going to be
possible...  am I understanding you correctly that normal SPI can't DMA?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131018/4ffd6461/attachment.sig>

From computersforpeace at gmail.com  Thu Oct 17 21:36:18 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 17 Oct 2013 18:36:18 -0700
Subject: [PATCH] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <1382001897-2709-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382001897-2709-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131018013618.GI23337@ld-irv-0074.broadcom.com>

On Thu, Oct 17, 2013 at 06:24:57AM -0300, Ezequiel Garcia wrote:
> In a recent commit:
> 
>   commit f455578dd961087a5cf94730d9f6489bb1d355f0
>   Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
>   Date:   Mon Aug 12 14:14:53 2013 -0300
> 
>   mtd: nand: pxa3xx: Remove hardcoded mtd name
> 
>   There's no advantage in using a hardcoded name for the mtd device.
>   Instead use the provided by the platform_device.
> 
> The MTD name was changed to use the one provided by the platform_device.
> However, this can be problematic as some users want to set partitions
> using the kernel parameter 'mtdpart', where the name is needed.
> 
> For that reason, using a simpler and easier to remember name such
> as 'pxa3xx-nand' is certainly a better choice.

Hmm, if we're really interested in the user experience of 'mtdparts'
users, shouldn't we just revert to the old name ("pxa3xx_nand-0") to
avoid breaking systems? Or are there no users that would care?

Brian


From sourav.poddar at ti.com  Fri Oct 18 00:06:06 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 18 Oct 2013 09:36:06 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131017234230.GZ2443@sirena.org.uk>
References: <20131015111647.GX2443@sirena.org.uk> <525D2BB3.4020705@ti.com>
 <20131015124656.GM2443@sirena.org.uk> <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
 <20131017234230.GZ2443@sirena.org.uk>
Message-ID: <5260B3AE.9070308@ti.com>

On Friday 18 October 2013 05:12 AM, Mark Brown wrote:
> On Thu, Oct 17, 2013 at 01:03:26PM +0000, Gupta, Pekon wrote:
>
>> mtd_read() {
>> 	if (flash->mmap_mode)
>> 		if (dma_available)
>> 			read_via_dma(destination, source, length);
>> 		else
>> 			memcpy(destination, source, length);
>> 	else
>> 		/* use spi frame-work by default */
>> }
>> Are you looking for comparison between  read_via_dma() v/s memcpy() ?
> No, I'm looking for a comparison of normal SPI mode (which I'd have
> expected to DMA) and the memcpy() mode.
>
>> If yes, then unfortunately we are bit constrained because our controller
>> does not support DMA. So, we have to depend on CPU based memcpy()
>> only. However, use of DMA can be added as an independent patch on
>> top of this CASE-2 patch.
> However if the controller can't DMA at all then that's not going to be
> possible...  am I understanding you correctly that normal SPI can't DMA?
Yes, you are correct, the normal SPI cant DMA.


From tpiepho at gmail.com  Fri Oct 18 01:56:53 2013
From: tpiepho at gmail.com (Trent Piepho)
Date: Thu, 17 Oct 2013 22:56:53 -0700
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <5260B3AE.9070308@ti.com>
References: <20131015111647.GX2443@sirena.org.uk> <525D2BB3.4020705@ti.com>
 <20131015124656.GM2443@sirena.org.uk> <525D41E2.30206@ti.com>
 <20131015180142.GS23337@ld-irv-0074.broadcom.com>
 <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
 <20131017234230.GZ2443@sirena.org.uk> <5260B3AE.9070308@ti.com>
Message-ID: <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>

On Thu, Oct 17, 2013 at 9:06 PM, Sourav Poddar <sourav.poddar at ti.com> wrote:
> On Friday 18 October 2013 05:12 AM, Mark Brown wrote:
>>> Are you looking for comparison between  read_via_dma() v/s memcpy() ?
>>
>> No, I'm looking for a comparison of normal SPI mode (which I'd have
>> expected to DMA) and the memcpy() mode.
>>
>>> If yes, then unfortunately we are bit constrained because our controller
>>> does not support DMA. So, we have to depend on CPU based memcpy()
>>> only. However, use of DMA can be added as an independent patch on
>>> top of this CASE-2 patch.
>>
>> However if the controller can't DMA at all then that's not going to be
>> possible...  am I understanding you correctly that normal SPI can't DMA?
>
> Yes, you are correct, the normal SPI cant DMA.

Hardware limitation or driver limitation?  Adding DMA support to the
driver might be much more useful than adding memory mapped read
support.


From sourav.poddar at ti.com  Fri Oct 18 02:10:15 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 18 Oct 2013 11:40:15 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
References: <20131015111647.GX2443@sirena.org.uk>	<525D2BB3.4020705@ti.com>	<20131015124656.GM2443@sirena.org.uk>	<525D41E2.30206@ti.com>	<20131015180142.GS23337@ld-irv-0074.broadcom.com>	<CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>	<20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>	<525FD715.50703@ti.com>	<20131017123850.GN2443@sirena.org.uk>	<20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>	<20131017234230.GZ2443@sirena.org.uk>	<5260B3AE.9070308@ti.com>
 <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
Message-ID: <5260D0C7.4000805@ti.com>

On Friday 18 October 2013 11:26 AM, Trent Piepho wrote:
> On Thu, Oct 17, 2013 at 9:06 PM, Sourav Poddar<sourav.poddar at ti.com>  wrote:
>> On Friday 18 October 2013 05:12 AM, Mark Brown wrote:
>>>> Are you looking for comparison between  read_via_dma() v/s memcpy() ?
>>> No, I'm looking for a comparison of normal SPI mode (which I'd have
>>> expected to DMA) and the memcpy() mode.
>>>
>>>> If yes, then unfortunately we are bit constrained because our controller
>>>> does not support DMA. So, we have to depend on CPU based memcpy()
>>>> only. However, use of DMA can be added as an independent patch on
>>>> top of this CASE-2 patch.
>>> However if the controller can't DMA at all then that's not going to be
>>> possible...  am I understanding you correctly that normal SPI can't DMA?
>> Yes, you are correct, the normal SPI cant DMA.
> Hardware limitation or driver limitation?  Adding DMA support to the
> driver might be much more useful than adding memory mapped read
> support.
Its a hardware limitation, the qspi controller does not support DMA.


From b32955 at freescale.com  Fri Oct 18 02:20:53 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Fri, 18 Oct 2013 14:20:53 +0800
Subject: [PATCH] mtd: nand: use a local variable to simplify the nand_scan_tail
Message-ID: <1382077253-21709-1-git-send-email-b32955@freescale.com>

There are too many "chip->ecc" in the nand_scan_tail() which makes the eyes
sore.

This patch uses a local variable "ecc" to replace the "chip->ecc" to
make the code more graceful.

Do the code change with "s/chip->ecc\./ecc->/g" in the nand_scan_tail,
and also change some lines by hand.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 drivers/mtd/nand/nand_base.c |  213 ++++++++++++++++++++---------------------
 1 files changed, 104 insertions(+), 109 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 8488844..b60c204 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -3547,6 +3547,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
+	struct nand_ecc_ctrl *ecc = &chip->ecc;
 
 	/* New bad blocks should be marked in OOB, flash-based BBT, or both */
 	BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
@@ -3563,19 +3564,19 @@ int nand_scan_tail(struct mtd_info *mtd)
 	/*
 	 * If no default placement scheme is given, select an appropriate one.
 	 */
-	if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) {
+	if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
 		switch (mtd->oobsize) {
 		case 8:
-			chip->ecc.layout = &nand_oob_8;
+			ecc->layout = &nand_oob_8;
 			break;
 		case 16:
-			chip->ecc.layout = &nand_oob_16;
+			ecc->layout = &nand_oob_16;
 			break;
 		case 64:
-			chip->ecc.layout = &nand_oob_64;
+			ecc->layout = &nand_oob_64;
 			break;
 		case 128:
-			chip->ecc.layout = &nand_oob_128;
+			ecc->layout = &nand_oob_128;
 			break;
 		default:
 			pr_warn("No oob scheme defined for oobsize %d\n",
@@ -3592,64 +3593,62 @@ int nand_scan_tail(struct mtd_info *mtd)
 	 * selected and we have 256 byte pagesize fallback to software ECC
 	 */
 
-	switch (chip->ecc.mode) {
+	switch (ecc->mode) {
 	case NAND_ECC_HW_OOB_FIRST:
 		/* Similar to NAND_ECC_HW, but a separate read_page handle */
-		if (!chip->ecc.calculate || !chip->ecc.correct ||
-		     !chip->ecc.hwctl) {
+		if (!ecc->calculate || !ecc->correct || !ecc->hwctl) {
 			pr_warn("No ECC functions supplied; "
 				   "hardware ECC not possible\n");
 			BUG();
 		}
-		if (!chip->ecc.read_page)
-			chip->ecc.read_page = nand_read_page_hwecc_oob_first;
+		if (!ecc->read_page)
+			ecc->read_page = nand_read_page_hwecc_oob_first;
 
 	case NAND_ECC_HW:
 		/* Use standard hwecc read page function? */
-		if (!chip->ecc.read_page)
-			chip->ecc.read_page = nand_read_page_hwecc;
-		if (!chip->ecc.write_page)
-			chip->ecc.write_page = nand_write_page_hwecc;
-		if (!chip->ecc.read_page_raw)
-			chip->ecc.read_page_raw = nand_read_page_raw;
-		if (!chip->ecc.write_page_raw)
-			chip->ecc.write_page_raw = nand_write_page_raw;
-		if (!chip->ecc.read_oob)
-			chip->ecc.read_oob = nand_read_oob_std;
-		if (!chip->ecc.write_oob)
-			chip->ecc.write_oob = nand_write_oob_std;
-		if (!chip->ecc.read_subpage)
-			chip->ecc.read_subpage = nand_read_subpage;
-		if (!chip->ecc.write_subpage)
-			chip->ecc.write_subpage = nand_write_subpage_hwecc;
+		if (!ecc->read_page)
+			ecc->read_page = nand_read_page_hwecc;
+		if (!ecc->write_page)
+			ecc->write_page = nand_write_page_hwecc;
+		if (!ecc->read_page_raw)
+			ecc->read_page_raw = nand_read_page_raw;
+		if (!ecc->write_page_raw)
+			ecc->write_page_raw = nand_write_page_raw;
+		if (!ecc->read_oob)
+			ecc->read_oob = nand_read_oob_std;
+		if (!ecc->write_oob)
+			ecc->write_oob = nand_write_oob_std;
+		if (!ecc->read_subpage)
+			ecc->read_subpage = nand_read_subpage;
+		if (!ecc->write_subpage)
+			ecc->write_subpage = nand_write_subpage_hwecc;
 
 	case NAND_ECC_HW_SYNDROME:
-		if ((!chip->ecc.calculate || !chip->ecc.correct ||
-		     !chip->ecc.hwctl) &&
-		    (!chip->ecc.read_page ||
-		     chip->ecc.read_page == nand_read_page_hwecc ||
-		     !chip->ecc.write_page ||
-		     chip->ecc.write_page == nand_write_page_hwecc)) {
+		if ((!ecc->calculate || !ecc->correct || !ecc->hwctl) &&
+		    (!ecc->read_page ||
+		     ecc->read_page == nand_read_page_hwecc ||
+		     !ecc->write_page ||
+		     ecc->write_page == nand_write_page_hwecc)) {
 			pr_warn("No ECC functions supplied; "
 				   "hardware ECC not possible\n");
 			BUG();
 		}
 		/* Use standard syndrome read/write page function? */
-		if (!chip->ecc.read_page)
-			chip->ecc.read_page = nand_read_page_syndrome;
-		if (!chip->ecc.write_page)
-			chip->ecc.write_page = nand_write_page_syndrome;
-		if (!chip->ecc.read_page_raw)
-			chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
-		if (!chip->ecc.write_page_raw)
-			chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
-		if (!chip->ecc.read_oob)
-			chip->ecc.read_oob = nand_read_oob_syndrome;
-		if (!chip->ecc.write_oob)
-			chip->ecc.write_oob = nand_write_oob_syndrome;
-
-		if (mtd->writesize >= chip->ecc.size) {
-			if (!chip->ecc.strength) {
+		if (!ecc->read_page)
+			ecc->read_page = nand_read_page_syndrome;
+		if (!ecc->write_page)
+			ecc->write_page = nand_write_page_syndrome;
+		if (!ecc->read_page_raw)
+			ecc->read_page_raw = nand_read_page_raw_syndrome;
+		if (!ecc->write_page_raw)
+			ecc->write_page_raw = nand_write_page_raw_syndrome;
+		if (!ecc->read_oob)
+			ecc->read_oob = nand_read_oob_syndrome;
+		if (!ecc->write_oob)
+			ecc->write_oob = nand_write_oob_syndrome;
+
+		if (mtd->writesize >= ecc->size) {
+			if (!ecc->strength) {
 				pr_warn("Driver must set ecc.strength when using hardware ECC\n");
 				BUG();
 			}
@@ -3657,23 +3656,23 @@ int nand_scan_tail(struct mtd_info *mtd)
 		}
 		pr_warn("%d byte HW ECC not possible on "
 			   "%d byte page size, fallback to SW ECC\n",
-			   chip->ecc.size, mtd->writesize);
-		chip->ecc.mode = NAND_ECC_SOFT;
+			   ecc->size, mtd->writesize);
+		ecc->mode = NAND_ECC_SOFT;
 
 	case NAND_ECC_SOFT:
-		chip->ecc.calculate = nand_calculate_ecc;
-		chip->ecc.correct = nand_correct_data;
-		chip->ecc.read_page = nand_read_page_swecc;
-		chip->ecc.read_subpage = nand_read_subpage;
-		chip->ecc.write_page = nand_write_page_swecc;
-		chip->ecc.read_page_raw = nand_read_page_raw;
-		chip->ecc.write_page_raw = nand_write_page_raw;
-		chip->ecc.read_oob = nand_read_oob_std;
-		chip->ecc.write_oob = nand_write_oob_std;
-		if (!chip->ecc.size)
-			chip->ecc.size = 256;
-		chip->ecc.bytes = 3;
-		chip->ecc.strength = 1;
+		ecc->calculate = nand_calculate_ecc;
+		ecc->correct = nand_correct_data;
+		ecc->read_page = nand_read_page_swecc;
+		ecc->read_subpage = nand_read_subpage;
+		ecc->write_page = nand_write_page_swecc;
+		ecc->read_page_raw = nand_read_page_raw;
+		ecc->write_page_raw = nand_write_page_raw;
+		ecc->read_oob = nand_read_oob_std;
+		ecc->write_oob = nand_write_oob_std;
+		if (!ecc->size)
+			ecc->size = 256;
+		ecc->bytes = 3;
+		ecc->strength = 1;
 		break;
 
 	case NAND_ECC_SOFT_BCH:
@@ -3681,87 +3680,83 @@ int nand_scan_tail(struct mtd_info *mtd)
 			pr_warn("CONFIG_MTD_ECC_BCH not enabled\n");
 			BUG();
 		}
-		chip->ecc.calculate = nand_bch_calculate_ecc;
-		chip->ecc.correct = nand_bch_correct_data;
-		chip->ecc.read_page = nand_read_page_swecc;
-		chip->ecc.read_subpage = nand_read_subpage;
-		chip->ecc.write_page = nand_write_page_swecc;
-		chip->ecc.read_page_raw = nand_read_page_raw;
-		chip->ecc.write_page_raw = nand_write_page_raw;
-		chip->ecc.read_oob = nand_read_oob_std;
-		chip->ecc.write_oob = nand_write_oob_std;
+		ecc->calculate = nand_bch_calculate_ecc;
+		ecc->correct = nand_bch_correct_data;
+		ecc->read_page = nand_read_page_swecc;
+		ecc->read_subpage = nand_read_subpage;
+		ecc->write_page = nand_write_page_swecc;
+		ecc->read_page_raw = nand_read_page_raw;
+		ecc->write_page_raw = nand_write_page_raw;
+		ecc->read_oob = nand_read_oob_std;
+		ecc->write_oob = nand_write_oob_std;
 		/*
 		 * Board driver should supply ecc.size and ecc.bytes values to
 		 * select how many bits are correctable; see nand_bch_init()
 		 * for details. Otherwise, default to 4 bits for large page
 		 * devices.
 		 */
-		if (!chip->ecc.size && (mtd->oobsize >= 64)) {
-			chip->ecc.size = 512;
-			chip->ecc.bytes = 7;
+		if (!ecc->size && (mtd->oobsize >= 64)) {
+			ecc->size = 512;
+			ecc->bytes = 7;
 		}
-		chip->ecc.priv = nand_bch_init(mtd,
-					       chip->ecc.size,
-					       chip->ecc.bytes,
-					       &chip->ecc.layout);
-		if (!chip->ecc.priv) {
+		ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes,
+					       &ecc->layout);
+		if (!ecc->priv) {
 			pr_warn("BCH ECC initialization failed!\n");
 			BUG();
 		}
-		chip->ecc.strength =
-			chip->ecc.bytes * 8 / fls(8 * chip->ecc.size);
+		ecc->strength = ecc->bytes * 8 / fls(8 * ecc->size);
 		break;
 
 	case NAND_ECC_NONE:
 		pr_warn("NAND_ECC_NONE selected by board driver. "
 			   "This is not recommended!\n");
-		chip->ecc.read_page = nand_read_page_raw;
-		chip->ecc.write_page = nand_write_page_raw;
-		chip->ecc.read_oob = nand_read_oob_std;
-		chip->ecc.read_page_raw = nand_read_page_raw;
-		chip->ecc.write_page_raw = nand_write_page_raw;
-		chip->ecc.write_oob = nand_write_oob_std;
-		chip->ecc.size = mtd->writesize;
-		chip->ecc.bytes = 0;
-		chip->ecc.strength = 0;
+		ecc->read_page = nand_read_page_raw;
+		ecc->write_page = nand_write_page_raw;
+		ecc->read_oob = nand_read_oob_std;
+		ecc->read_page_raw = nand_read_page_raw;
+		ecc->write_page_raw = nand_write_page_raw;
+		ecc->write_oob = nand_write_oob_std;
+		ecc->size = mtd->writesize;
+		ecc->bytes = 0;
+		ecc->strength = 0;
 		break;
 
 	default:
-		pr_warn("Invalid NAND_ECC_MODE %d\n", chip->ecc.mode);
+		pr_warn("Invalid NAND_ECC_MODE %d\n", ecc->mode);
 		BUG();
 	}
 
 	/* For many systems, the standard OOB write also works for raw */
-	if (!chip->ecc.read_oob_raw)
-		chip->ecc.read_oob_raw = chip->ecc.read_oob;
-	if (!chip->ecc.write_oob_raw)
-		chip->ecc.write_oob_raw = chip->ecc.write_oob;
+	if (!ecc->read_oob_raw)
+		ecc->read_oob_raw = ecc->read_oob;
+	if (!ecc->write_oob_raw)
+		ecc->write_oob_raw = ecc->write_oob;
 
 	/*
 	 * The number of bytes available for a client to place data into
 	 * the out of band area.
 	 */
-	chip->ecc.layout->oobavail = 0;
-	for (i = 0; chip->ecc.layout->oobfree[i].length
-			&& i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++)
-		chip->ecc.layout->oobavail +=
-			chip->ecc.layout->oobfree[i].length;
-	mtd->oobavail = chip->ecc.layout->oobavail;
+	ecc->layout->oobavail = 0;
+	for (i = 0; ecc->layout->oobfree[i].length
+			&& i < ARRAY_SIZE(ecc->layout->oobfree); i++)
+		ecc->layout->oobavail += ecc->layout->oobfree[i].length;
+	mtd->oobavail = ecc->layout->oobavail;
 
 	/*
 	 * 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) {
+	ecc->steps = mtd->writesize / ecc->size;
+	if (ecc->steps * ecc->size != mtd->writesize) {
 		pr_warn("Invalid ECC parameters\n");
 		BUG();
 	}
-	chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;
+	ecc->total = ecc->steps * ecc->bytes;
 
 	/* Allow subpage writes up to ecc.steps. Not possible for MLC flash */
 	if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && nand_is_slc(chip)) {
-		switch (chip->ecc.steps) {
+		switch (ecc->steps) {
 		case 2:
 			mtd->subpage_sft = 1;
 			break;
@@ -3781,7 +3776,7 @@ int nand_scan_tail(struct mtd_info *mtd)
 	chip->pagebuf = -1;
 
 	/* Large page NAND with SOFT_ECC should support subpage reads */
-	if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+	if ((ecc->mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
 		chip->options |= NAND_SUBPAGE_READ;
 
 	/* Fill in remaining MTD driver data */
@@ -3806,9 +3801,9 @@ int nand_scan_tail(struct mtd_info *mtd)
 	mtd->writebufsize = mtd->writesize;
 
 	/* propagate ecc info to mtd_info */
-	mtd->ecclayout = chip->ecc.layout;
-	mtd->ecc_strength = chip->ecc.strength;
-	mtd->ecc_step_size = chip->ecc.size;
+	mtd->ecclayout = ecc->layout;
+	mtd->ecc_strength = ecc->strength;
+	mtd->ecc_step_size = ecc->size;
 	/*
 	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
 	 * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be
-- 
1.7.2.rc3




From b32955 at freescale.com  Fri Oct 18 02:50:26 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Fri, 18 Oct 2013 14:50:26 +0800
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <1377595747-21033-1-git-send-email-b32955@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>
Message-ID: <5260DA32.4090502@freescale.com>

? 2013?08?27? 17:29, Huang Shijie ??:
> Current gpmi-nand driver only supports one chips. But we may meet
> some embarrassing situation, such as Micron MT29F32G08QAA.
> This nand chip has two DIEs internally. Each die has its own chip select pin,
> so this chip acts as two nand chips.
>
> If we only scan one chip, we may find that we only get 2G for this chip,
> but in actually, this chip's size is 4G.
>
> So scan two chips by default.
>
> In order to support two nand chips, we have to do the following:
>    1.) Decouple the chip select from the DMA channel,
>        We can use the dma 0 to access all the nand chips.
>
>    2.) fix the wrong method of checking the ready/busy status.
>       In the imx6, all the ready/busy pins are binding together, we
>       should check ready/busy status of chip 0 for the all the chips. 
>
> Tested this patch set with MT29F32G08QAA.
>
> To Brian:
> 	My "better" solution was proved to be a bad idea. So i resend this
> 	patch set again.
>
> v1 --> v2:
> 	[0] rebase on the latest l2-mtd tree.
>
> Huang Shijie (4):
>   mtd: gpmi: decouple the chip select from the DMA channel
>   mtd: gpmi: use DMA channel 0 for all the nand chips
>   mtd: gpmi: scan two nand chips
>   mtd: gpmi: imx6: fix the wrong method for checking ready/busy
>
>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |   13 +++++++++++++
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    7 +++----
>  drivers/mtd/nand/gpmi-nand/gpmi-regs.h |    3 +++
>  3 files changed, 19 insertions(+), 4 deletions(-)
>
Hi Artem & Brian:
Could you please merge this patch set?
it seems you have missed this patch set.


thanks
Huang Shijie



From sourav.poddar at ti.com  Fri Oct 18 03:27:51 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 18 Oct 2013 12:57:51 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <5260D0C7.4000805@ti.com>
References: <20131015111647.GX2443@sirena.org.uk>	<525D2BB3.4020705@ti.com>	<20131015124656.GM2443@sirena.org.uk>	<525D41E2.30206@ti.com>	<20131015180142.GS23337@ld-irv-0074.broadcom.com>	<CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>	<20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>	<525FD715.50703@ti.com>	<20131017123850.GN2443@sirena.org.uk>	<20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>	<20131017234230.GZ2443@sirena.org.uk>	<5260B3AE.9070308@ti.com>
 <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
 <5260D0C7.4000805@ti.com>
Message-ID: <5260E2F7.4020404@ti.com>

Hi,
On Friday 18 October 2013 11:40 AM, Sourav Poddar wrote:
> On Friday 18 October 2013 11:26 AM, Trent Piepho wrote:
>> On Thu, Oct 17, 2013 at 9:06 PM, Sourav Poddar<sourav.poddar at ti.com>  
>> wrote:
>>> On Friday 18 October 2013 05:12 AM, Mark Brown wrote:
>>>>> Are you looking for comparison between  read_via_dma() v/s memcpy() ?
>>>> No, I'm looking for a comparison of normal SPI mode (which I'd have
>>>> expected to DMA) and the memcpy() mode.
>>>>
>>>>> If yes, then unfortunately we are bit constrained because our 
>>>>> controller
>>>>> does not support DMA. So, we have to depend on CPU based memcpy()
>>>>> only. However, use of DMA can be added as an independent patch on
>>>>> top of this CASE-2 patch.
>>>> However if the controller can't DMA at all then that's not going to be
>>>> possible...  am I understanding you correctly that normal SPI can't 
>>>> DMA?
>>> Yes, you are correct, the normal SPI cant DMA.
>> Hardware limitation or driver limitation?  Adding DMA support to the
>> driver might be much more useful than adding memory mapped read
>> support.
> Its a hardware limitation, the qspi controller does not support DMA.
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/
So, consolidating all the comments, this is what can be done to improve the
$subject patch..

1. Keep the qspi controller by default in memory mapped mode.

2. While doing operations other than memory mapped, change the
     controller into config mode and at the end change it into memory mapped
     mode.

3. For filling memory mapped register in qspi controller, we can pass 
that information
     from dt rather than hardcoding as macros.

4. For memory mapped read, do the memcpy in the mtd_read itself and 
bypass the
     SPI framework.
      This has two points to be considered -

     4a.
         Roadblock:
          To get the mem buf from the spi controller to mtd layer
          Solution:
            As suggested by Mark, we can define some apis like
              get_buf/free_buf  in mtd driver and use that to get the
              buf.

     4b.
         Roadblock:
         Runtime clock management is handle by SPI framework, so while
         doing memory read, where we bypass SPI framework, clocks will be
         disable and we will get an abort while doing memcpy.

        Possible solution:
            As suggested by Trent, we can keep the SPI controller clocks 
always ON ?


If the above proposal looks good, should I go ahead and post the next 
updated
patch series?




From ezequiel.garcia at free-electrons.com  Fri Oct 18 05:33:17 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 06:33:17 -0300
Subject: [PATCH] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <20131018013618.GI23337@ld-irv-0074.broadcom.com>
References: <1382001897-2709-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131018013618.GI23337@ld-irv-0074.broadcom.com>
Message-ID: <20131018093316.GA18998@localhost>

On Thu, Oct 17, 2013 at 06:36:18PM -0700, Brian Norris wrote:
> On Thu, Oct 17, 2013 at 06:24:57AM -0300, Ezequiel Garcia wrote:
> > In a recent commit:
> > 
> >   commit f455578dd961087a5cf94730d9f6489bb1d355f0
> >   Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> >   Date:   Mon Aug 12 14:14:53 2013 -0300
> > 
> >   mtd: nand: pxa3xx: Remove hardcoded mtd name
> > 
> >   There's no advantage in using a hardcoded name for the mtd device.
> >   Instead use the provided by the platform_device.
> > 
> > The MTD name was changed to use the one provided by the platform_device.
> > However, this can be problematic as some users want to set partitions
> > using the kernel parameter 'mtdpart', where the name is needed.
> > 
> > For that reason, using a simpler and easier to remember name such
> > as 'pxa3xx-nand' is certainly a better choice.
> 
> Hmm, if we're really interested in the user experience of 'mtdparts'
> users, shouldn't we just revert to the old name ("pxa3xx_nand-0") to
> avoid breaking systems? Or are there no users that would care?
> 

Dammit! yes, that's the intention of this patch: revert to the old name
"pxa3xx_nand-0" to avoid breaking systems.

Guess I couldn't manage my OCD and picked a more appealing name :)

I'll send a v2 right away.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From broonie at kernel.org  Fri Oct 18 06:31:14 2013
From: broonie at kernel.org (Mark Brown)
Date: Fri, 18 Oct 2013 11:31:14 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <5260E2F7.4020404@ti.com>
References: <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
 <20131017234230.GZ2443@sirena.org.uk> <5260B3AE.9070308@ti.com>
 <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
 <5260D0C7.4000805@ti.com> <5260E2F7.4020404@ti.com>
Message-ID: <20131018103114.GJ2443@sirena.org.uk>

On Fri, Oct 18, 2013 at 12:57:51PM +0530, Sourav Poddar wrote:

> 3. For filling memory mapped register in qspi controller, we can
> pass that information
>     from dt rather than hardcoding as macros.

Or from the flash driver at runtime...

>     4b.
>         Roadblock:
>         Runtime clock management is handle by SPI framework, so while
>         doing memory read, where we bypass SPI framework, clocks will be
>         disable and we will get an abort while doing memcpy.

>        Possible solution:
>            As suggested by Trent, we can keep the SPI controller
> clocks always ON ?

At the SPI layer I would keep the clocks on while the driver has a
region mapped for the flash layer.  The flash layer can then decide when
to keep the region mapped, for example it could do so whenever the
device is opened.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131018/0dbec24e/attachment.sig>

From sachin.kamat at linaro.org  Fri Oct 18 06:46:35 2013
From: sachin.kamat at linaro.org (Sachin Kamat)
Date: Fri, 18 Oct 2013 16:16:35 +0530
Subject: [PATCH 1/1] mtd: mxc_nand: Include linux/of.h header
Message-ID: <1382093195-31929-1-git-send-email-sachin.kamat@linaro.org>

'of_match_ptr' is defined in linux/of.h. Include it explicitly to
avoid build breakage in the future.

Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
---
 drivers/mtd/nand/mxc_nand.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index ce8242b..1037755 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/completion.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_mtd.h>
 
-- 
1.7.9.5



From mark.rutland at arm.com  Fri Oct 18 06:59:17 2013
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 18 Oct 2013 11:59:17 +0100
Subject: [PATCH v9 1/9] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <1381816197-20477-2-git-send-email-pekon@ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-2-git-send-email-pekon@ti.com>
Message-ID: <20131018105917.GE29779@e106331-lin.cambridge.arm.com>

Hi Pekon,

On Tue, Oct 15, 2013 at 06:49:49AM +0100, Pekon Gupta wrote:
> OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
> ecc-scheme, like:
> - OMAP_ECC_HAMMING_CODE_DEFAULT
> 	1-bit hamming ecc code using software library
> - OMAP_ECC_HAMMING_CODE_HW
> 	1-bit hamming ecc-code using GPMC h/w engine
> - OMAP_ECC_HAMMING_CODE_HW_ROMCODE
> 	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
> 	to ROM code.
> 
> This patch combines above multiple ecc-schemes into single implementation:
> - OMAP_ECC_HAM1_CODE_HW
> 	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
> 	ecc-layout.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> Reviewed-by: Felipe Balbi <balbi at ti.com>
> Acked-by: Tony Lindgren <tony at atomide.com>
> ---
>  Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
>  arch/arm/mach-omap2/board-flash.c                   | 2 +-
>  arch/arm/mach-omap2/gpmc.c                          | 4 +---
>  drivers/mtd/nand/omap2.c                            | 9 +++------
>  include/linux/platform_data/mtd-nand-omap2.h        | 6 +-----
>  5 files changed, 10 insertions(+), 19 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> index df338cb..25ee232 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> @@ -22,10 +22,10 @@ Optional properties:
>  				width of 8 is assumed.
>  
>   - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
> -
> -		"sw"		Software method (default)
> -		"hw"		Hardware method
> -		"hw-romcode"	gpmc hamming mode method & romcode layout
> +		"sw"		<deprecated> use "ham1" instead
> +		"hw"		<deprecated> use "ham1" instead
> +		"hw-romcode"	<deprecated> use "ham1" instead
> +		"ham1"		1-bit Hamming ecc code
>  		"bch4"		4-bit BCH ecc code
>  		"bch8"		8-bit BCH ecc code

[...]

> diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
> index 579697a..c9fb353 100644
> --- a/arch/arm/mach-omap2/gpmc.c
> +++ b/arch/arm/mach-omap2/gpmc.c
> @@ -1342,9 +1342,7 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  #ifdef CONFIG_MTD_NAND
>  
>  static const char * const nand_ecc_opts[] = {
> -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
> +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
>  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
>  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
>  };

As the parsing isn't updated until the next patch, doesn't this
temporarily break DTBs with the deprecated ti,nand-ecc-opt values?

Thanks,
Mark.


From simon at liddicott.com  Fri Oct 18 07:41:50 2013
From: simon at liddicott.com (Simon Liddicott)
Date: Fri, 18 Oct 2013 12:41:50 +0100
Subject: nandsim LEB size mismatch
In-Reply-To: <CALuNSF7ESa0CBE0+kNO_HDeWKVgzN8ZZo7TnNGadTC0AuZjEXQ@mail.gmail.com>
References: <CALuNSF7ESa0CBE0+kNO_HDeWKVgzN8ZZo7TnNGadTC0AuZjEXQ@mail.gmail.com>
Message-ID: <CALuNSF7A=PBpyP4=nEEKvuhAMAQJvucGddhHPuxSuqZuCTnmEg@mail.gmail.com>

On 11 October 2013 14:57, Simon Liddicott <simon at liddicott.com> wrote:
> Hi
>
> I've searched the archives and read the FAQ but not found anything
> that matches my situation.
>
> I am trying to read an image I think is made for an MT29F2G08ABAEA.
>
> I have run the following:
>
> $ sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xda \
> third_id_byte=0x90 fourth_id_byte=0x95
> $ sudo flash_erase /dev/mtd0 0 0
> $ sudo modprobe ubi mtd=0
> $ sudo ubimkvol /dev/ubi0 -N RFS -s $((0xA00000))
>
> Volume ID 0, size 82 LEBs (10579968 bytes, 10.1 MiB), LEB size 129024
> bytes (126.0 KiB), dynamic, name "RFS", alignment 1
>
> $ sudo ubiupdatevol /dev/ubi0_0 RFS.bin
> $ sudo mount /dev/ubi0_0 /mnt
>
> mount: wrong fs type, bad option, bad superblock on /dev/ubi0_0,
>        missing codepage or helper program, or other error
>        In some cases useful info is found in syslog - try
>        dmesg | tail  or so
>
> [1975256.515179] UBIFS error (pid 10309): validate_sb: LEB size
> mismatch: 126976 in superblock, 129024 real
>
> I think that nandsim provides the 'real' value for LEB size, and even
> if the value is right - how can I read the data that expects a 124KiB
> LEB size?
>
> Any help appreciated.
>
> Thanks in advance.
>
> Simon.


I didn't get a reply, but have managed to find out how to do it.

The correct instructions should be:
$ sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xda \
third_id_byte=0x90 fourth_id_byte=0x95
$ sudo flash_erase /dev/mtd0 0 0
$ sudo ubiformat /dev/mtd0 -s 2048 -O 2048
$ sudo modprobe ubi
$ sudo ubiattach -m 0 -d 0 -O 2048
$ sudo ubimkvol /dev/ubi0 -N RFS -s $((0xA00000))
$ sudo ubiupdatevol /dev/ubi0_0 RFS.bin
$ sudo mount /dev/ubi0_0 /mnt

Success!


From sourav.poddar at ti.com  Fri Oct 18 07:48:15 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 18 Oct 2013 17:18:15 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131018103114.GJ2443@sirena.org.uk>
References: <CA+7tXigv1Q3BPE3uhzdJpx3DsqUpxzrBUaPfWR-i15PsVtMWsQ@mail.gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA23640@DBDE04.ent.ti.com>
 <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
 <20131017234230.GZ2443@sirena.org.uk> <5260B3AE.9070308@ti.com>
 <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
 <5260D0C7.4000805@ti.com> <5260E2F7.4020404@ti.com>
 <20131018103114.GJ2443@sirena.org.uk>
Message-ID: <52611FFF.9080601@ti.com>

On Friday 18 October 2013 04:01 PM, Mark Brown wrote:
> On Fri, Oct 18, 2013 at 12:57:51PM +0530, Sourav Poddar wrote:
>
>> 3. For filling memory mapped register in qspi controller, we can
>> pass that information
>>      from dt rather than hardcoding as macros.
> Or from the flash driver at runtime...
>
No, as for now, its better to keep mtd framework independent of this
spi controller configuration and pass the information via dt.

Since we dont have a common protocol, If we start putting this information
in mtd, it will clutter the mtd space and it may happen that we may end up
with differnet if defs for all the kind of flash devices.
>>      4b.
>>          Roadblock:
>>          Runtime clock management is handle by SPI framework, so while
>>          doing memory read, where we bypass SPI framework, clocks will be
>>          disable and we will get an abort while doing memcpy.
>>         Possible solution:
>>             As suggested by Trent, we can keep the SPI controller
>> clocks always ON ?
> At the SPI layer I would keep the clocks on while the driver has a
> region mapped for the flash layer.  The flash layer can then decide when
> to keep the region mapped, for example it could do so whenever the
> device is opened.



From pekon at ti.com  Fri Oct 18 07:48:31 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 18 Oct 2013 11:48:31 +0000
Subject: [PATCH v9 1/9] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <20131018105917.GE29779@e106331-lin.cambridge.arm.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-2-git-send-email-pekon@ti.com>
 <20131018105917.GE29779@e106331-lin.cambridge.arm.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA284F4@DBDE04.ent.ti.com>

Hi Mark,

> From: Mark Rutland
> [...]
> 
> > diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-
> omap2/gpmc.c
> > index 579697a..c9fb353 100644
> > --- a/arch/arm/mach-omap2/gpmc.c
> > +++ b/arch/arm/mach-omap2/gpmc.c
> > @@ -1342,9 +1342,7 @@ static void __maybe_unused
> gpmc_read_timings_dt(struct device_node *np,
> >  #ifdef CONFIG_MTD_NAND
> >
> >  static const char * const nand_ecc_opts[] = {
> > -	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
> > -	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
> > -	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-
> romcode",
> > +	[OMAP_ECC_HAM1_CODE_HW]			= "ham1",
> >  	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
> >  	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
> >  };
> 
> As the parsing isn't updated until the next patch, doesn't this
> temporarily break DTBs with the deprecated ti,nand-ecc-opt values?
> 
Ok then I'll swap the [Patch 1/9] and [Patch 2/9] so that DT parsing updates
(with backward compatibility) happen before the deprecation of DT values.
This way old DT binding would work all through.

And as DT parsing is kept backward compatible, so .dts changes would not
break the DTBs even if updated in separate patch.

with regards, pekon


From broonie at kernel.org  Fri Oct 18 09:08:42 2013
From: broonie at kernel.org (Mark Brown)
Date: Fri, 18 Oct 2013 14:08:42 +0100
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <52611FFF.9080601@ti.com>
References: <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
 <20131017234230.GZ2443@sirena.org.uk> <5260B3AE.9070308@ti.com>
 <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
 <5260D0C7.4000805@ti.com> <5260E2F7.4020404@ti.com>
 <20131018103114.GJ2443@sirena.org.uk> <52611FFF.9080601@ti.com>
Message-ID: <20131018130842.GO2443@sirena.org.uk>

On Fri, Oct 18, 2013 at 05:18:15PM +0530, Sourav Poddar wrote:
> On Friday 18 October 2013 04:01 PM, Mark Brown wrote:
> >On Fri, Oct 18, 2013 at 12:57:51PM +0530, Sourav Poddar wrote:

> >>3. For filling memory mapped register in qspi controller, we can
> >>pass that information
> >>     from dt rather than hardcoding as macros.

> >Or from the flash driver at runtime...

> No, as for now, its better to keep mtd framework independent of this
> spi controller configuration and pass the information via dt.

> Since we dont have a common protocol, If we start putting this information
> in mtd, it will clutter the mtd space and it may happen that we may end up
> with differnet if defs for all the kind of flash devices.

I thought this was the information for the flash commands that the
driver would need to know anyway for use with SPI controllers without
explicit flash support?  But perhaps I'm misunderstanding.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131018/6706ad0c/attachment.sig>

From pekon at ti.com  Fri Oct 18 10:11:19 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 18 Oct 2013 14:11:19 +0000
Subject: [PATCH] mtd: nand: use a local variable to simplify the
 nand_scan_tail
In-Reply-To: <1382077253-21709-1-git-send-email-b32955@freescale.com>
References: <1382077253-21709-1-git-send-email-b32955@freescale.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>

> From: Huang Shijie
> There are too many "chip->ecc" in the nand_scan_tail() which makes the
> eyes
> sore.
> 
> This patch uses a local variable "ecc" to replace the "chip->ecc" to
> make the code more graceful.
> 
> Do the code change with "s/chip->ecc\./ecc->/g" in the nand_scan_tail,
> and also change some lines by hand.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> 
Personally I won't prefer such stand-alone cleanup  _unless_ there is
major driver re-write of the code, because this breaks the traceability
via 'git blame'. And even in that case, this change should be applied first,
and the other functional updates later.

On same lines, I was trying to clean-up omap2.c driver with
s/info->nand\./nand_chip->/
But withheld it till the point when I had to almost re-write complete probe.
So, I first did this change, and then on top-of-it re-wrote the omap_nand_probe().


with regards, pekon


From sourav.poddar at ti.com  Fri Oct 18 10:47:08 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 18 Oct 2013 20:17:08 +0530
Subject: [PATCH 1/3] spi/qspi: Add memory mapped read support.
In-Reply-To: <20131018130842.GO2443@sirena.org.uk>
References: <525FD715.50703@ti.com> <20131017123850.GN2443@sirena.org.uk>
 <20980858CB6D3A4BAE95CA194937D5E73EA27E10@DBDE04.ent.ti.com>
 <20131017234230.GZ2443@sirena.org.uk> <5260B3AE.9070308@ti.com>
 <CA+7tXihUBXK61cRDmn3tnY9FM7FUSZrhPpLry2VAfvwWJpJ6gQ@mail.gmail.com>
 <5260D0C7.4000805@ti.com> <5260E2F7.4020404@ti.com>
 <20131018103114.GJ2443@sirena.org.uk> <52611FFF.9080601@ti.com>
 <20131018130842.GO2443@sirena.org.uk>
Message-ID: <526149EC.6000200@ti.com>

On Friday 18 October 2013 06:38 PM, Mark Brown wrote:
> On Fri, Oct 18, 2013 at 05:18:15PM +0530, Sourav Poddar wrote:
>> On Friday 18 October 2013 04:01 PM, Mark Brown wrote:
>>> On Fri, Oct 18, 2013 at 12:57:51PM +0530, Sourav Poddar wrote:
>>>> 3. For filling memory mapped register in qspi controller, we can
>>>> pass that information
>>>>      from dt rather than hardcoding as macros.
>>> Or from the flash driver at runtime...
>> No, as for now, its better to keep mtd framework independent of this
>> spi controller configuration and pass the information via dt.
>> Since we dont have a common protocol, If we start putting this information
>> in mtd, it will clutter the mtd space and it may happen that we may end up
>> with differnet if defs for all the kind of flash devices.
> I thought this was the information for the flash commands that the
> driver would need to know anyway for use with SPI controllers without
> explicit flash support?  But perhaps I'm misunderstanding.
Flash driver need to know them, but as of now, everything is done in a 
api mode
stuff in flash driver. As in, we have write/erase/read, quad_read 
(proposed through this
series) where we provide the commands directly. And to handle different 
flash types, we
use macros to decide which command set is used.

May be, this can come as a part of a seperate discussion to modify flash 
driver also to
take data(commands, other parameters) through dt.

Though, for the case in hand,  better to set up spi mem map specific 
registers with dts from
spi controller node itself.  There might be different varieties of 
flashes, with different commands
and cluttering mtd flash to configure a controller specific register 
does not look to be a good idea.



From tharvey at gateworks.com  Fri Oct 18 13:03:43 2013
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 18 Oct 2013 10:03:43 -0700
Subject: gpmi-mtd ecc regression
Message-ID: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>

Huang,

The patch you made to obtain ECC info from the chip
(http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/mtd/nand/gpmi-nand?id=2febcdf84b75aae627c61f0a5bf531a69299966c)
has caused a regression for an i.MX6 board I'm working with that uses
NAND and ubifs.

I'm using a Micron MT29F8G08
(http://download.micron.com/pdf/datasheets/flash/nand/2_4_8gb_nand_m49a.pdf)
which has:
page size: 2112 bytes (2048 + 64 bytes)
block size: 1056 words (1024 + 32 words)
plane size: 2 planes x 1024 blocks per plane
device size: 2Gb: 2048 blocks
ecc: 4bit

The legacy_set_geometry function comes up with:
gf_len=13
ecc_strength=8
page_size=2112
metadata_size=10
ecc_chunk_size=512
ecc_chunk_count=4
payload_size=2048
auxiliary_size=16
auxiliary_status_offset=12
block_mark_byte_offset=1999

and the new set_geometry_by_ecc_info comes up with:
gf_len=13
ecc_strength=4
page_size=2084
metadata_size=10
ecc_chunk_size=512
ecc_chunk_count=4
payload_size=2048
auxiliary_size=16
auxiliary_status_offset=12
block_mark_byte_offset=2018
block_mark_bit_offset=4

There are two discrepancies above:
 a) ecc_strength - this part has 4bit ecc but being detected as 8?
 b) page_size - the legacy function includes oob in page size, and the
new one does not

which is correct?

With your patch using the new function to detect ECC from the part,
booting to a ubifs that was flashed with uboot (which incidentally
also set ecc_strength=8) I get endless ECC failures:

[    3.946205] UBI: attaching mtd2 to ubi0
[    3.946585] UBI warning: ubi_io_read: error -74 (ECC error) while
reading 64 bytes from PEB 0:0, read only 64 bytes, retry
[    3.946785] UBI warning: ubi_io_read: error -74 (ECC error) while
reading 64 bytes from PEB 0:0, read only 64 bytes, retry
[    3.946983] UBI warning: ubi_io_read: error -74 (ECC error) while
reading 64 bytes from PEB 0:0, read only 64 bytes, retry
[    3.947177] UBI error: ubi_io_read: error -74 (ECC error) while
reading 64 bytes from PEB 0:0, read 64 bytes
[    3.947186] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc3+ #253
[    3.947192] Backtrace:
[    3.947220] [<8001265c>] (dump_backtrace+0x0/0x10c) from
[<800127fc>] (show_stack+0x18/0x1c)
[    3.947230]  r6:00000040 r5:ffffffb6 r4:00000000 r3:00000000
[    3.947247] [<800127e4>] (show_stack+0x0/0x1c) from [<80661820>]
(dump_stack+0x78/0x94)
[    3.947269] [<806617a8>] (dump_stack+0x0/0x94) from [<803b4ebc>]
(ubi_io_read+0x12c/0x364)
[    3.947274]  r4:bf09e000 r3:00000000
[    3.947285] [<803b4d90>] (ubi_io_read+0x0/0x364) from [<803b533c>]
(ubi_io_read_ec_hdr+0x60/0x330)
[    3.947295] [<803b52dc>] (ubi_io_read_ec_hdr+0x0/0x330) from
[<803bb2dc>] (ubi_attach+0x160/0x15f0)
[    3.947304] [<803bb17c>] (ubi_attach+0x0/0x15f0) from [<803ae5f0>]
(ubi_attach_mtd_dev+0x794/0xf18)
[    3.947319] [<803ade5c>] (ubi_attach_mtd_dev+0x0/0xf18) from
[<808d9850>] (ubi_init+0x1f8/0x2bc)
[    3.947330] [<808d9658>] (ubi_init+0x0/0x2bc) from [<80008880>]
(do_one_initcall+0xdc/0x194)
[    3.947342] [<800087a4>] (do_one_initcall+0x0/0x194) from
[<808aeb94>] (kernel_init_freeable+0x104/0x1d0)
[    3.952386] [<808d9658>] (ubi_init+0x0/0x2bc) from [<80008880>]
(do_one_initcall+0xdc/0x194)
[    3.960828] [<800087a4>] (do_one_initcall+0x0/0x194) from
[<808aeb94>] (kernel_init_freeable+0x104/0x1d0)
[    3.967418] [<800087a4>] (do_one_initcall+0x0/0x194) from
[<808aeb94>] (kernel_init_freeable+0x104/0x1d0)
[    3.967426] [<808aea90>] (kernel_init_freeable+0x0/0x1d0) from
[<8065c74c>] (kernel_init+0x10/0xec)

Ideas?

Thanks,

Tim


From ezequiel.garcia at free-electrons.com  Fri Oct 18 14:14:32 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 15:14:32 -0300
Subject: [PATCH v2] mtd: nand: pxa3xx: Fix registered MTD name
Message-ID: <1382120072-30057-1-git-send-email-ezequiel.garcia@free-electrons.com>

In a recent commit:

  commit f455578dd961087a5cf94730d9f6489bb1d355f0
  Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
  Date:   Mon Aug 12 14:14:53 2013 -0300

  mtd: nand: pxa3xx: Remove hardcoded mtd name

  There's no advantage in using a hardcoded name for the mtd device.
  Instead use the provided by the platform_device.

The MTD name was changed to use the one provided by the platform_device.
However, this can be problematic as some users want to set partitions
using the kernel parameter 'mtdpart', where the name is needed.

Therefore, to avoid regressions in users relying in 'mtdpart' we revert
the change and use the previous one 'pxa3xx_nand-0'.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
v1->v2:
  * Use exactly the same name as before, and avoid regressions
    instead of using any seemingly better or cleaner one.

 drivers/mtd/nand/pxa3xx_nand.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index aa75adf..4d53e8e 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -46,6 +46,8 @@
  */
 #define INIT_BUFFER_SIZE	256
 
+#define DRIVER_NAME		"pxa3xx_nand-0"
+
 /* registers and bit definitions */
 #define NDCR		(0x00) /* Control register */
 #define NDTR0CS0	(0x04) /* Timing Parameter 0 for CS0 */
@@ -1339,7 +1341,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 	for (cs = 0; cs < pdata->num_cs; cs++) {
 		struct mtd_info *mtd = info->host[cs]->mtd;
 
-		mtd->name = pdev->name;
+		mtd->name = DRIVER_NAME;
 		info->cs = cs;
 		ret = pxa3xx_nand_scan(mtd);
 		if (ret) {
@@ -1425,7 +1427,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
 
 static struct platform_driver pxa3xx_nand_driver = {
 	.driver = {
-		.name	= "pxa3xx-nand",
+		.name	= DRIVER_NAME,
 		.of_match_table = pxa3xx_nand_dt_ids,
 	},
 	.probe		= pxa3xx_nand_probe,
-- 
1.8.1.5



From computersforpeace at gmail.com  Fri Oct 18 15:15:39 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 18 Oct 2013 12:15:39 -0700
Subject: [PATCH v2] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <1382120072-30057-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382120072-30057-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <CAN8TOE-hxcaj79hTxDMzP1On69n=3QdBy45fjePLrQuzSvnnyw@mail.gmail.com>

On Fri, Oct 18, 2013 at 11:14 AM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> In a recent commit:
>
>   commit f455578dd961087a5cf94730d9f6489bb1d355f0
>   Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
>   Date:   Mon Aug 12 14:14:53 2013 -0300
>
>   mtd: nand: pxa3xx: Remove hardcoded mtd name
>
>   There's no advantage in using a hardcoded name for the mtd device.
>   Instead use the provided by the platform_device.
>
> The MTD name was changed to use the one provided by the platform_device.
> However, this can be problematic as some users want to set partitions
> using the kernel parameter 'mtdpart', where the name is needed.
>
> Therefore, to avoid regressions in users relying in 'mtdpart' we revert
> the change and use the previous one 'pxa3xx_nand-0'.
>
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

Should this be marked for -stable (or squeezed into 3.12-rc now), so
we don't leave the regression in 3.12?

> ---
> v1->v2:
>   * Use exactly the same name as before, and avoid regressions
>     instead of using any seemingly better or cleaner one.
>
>  drivers/mtd/nand/pxa3xx_nand.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> index aa75adf..4d53e8e 100644
> --- a/drivers/mtd/nand/pxa3xx_nand.c
> +++ b/drivers/mtd/nand/pxa3xx_nand.c
> @@ -46,6 +46,8 @@
>   */
>  #define INIT_BUFFER_SIZE       256
>
> +#define DRIVER_NAME            "pxa3xx_nand-0"
> +
>  /* registers and bit definitions */
>  #define NDCR           (0x00) /* Control register */
>  #define NDTR0CS0       (0x04) /* Timing Parameter 0 for CS0 */
> @@ -1339,7 +1341,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
>         for (cs = 0; cs < pdata->num_cs; cs++) {
>                 struct mtd_info *mtd = info->host[cs]->mtd;
>
> -               mtd->name = pdev->name;
> +               mtd->name = DRIVER_NAME;
>                 info->cs = cs;
>                 ret = pxa3xx_nand_scan(mtd);
>                 if (ret) {
> @@ -1425,7 +1427,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
>
>  static struct platform_driver pxa3xx_nand_driver = {
>         .driver = {
> -               .name   = "pxa3xx-nand",
> +               .name   = DRIVER_NAME,
>                 .of_match_table = pxa3xx_nand_dt_ids,
>         },
>         .probe          = pxa3xx_nand_probe,

For mtdparts' sake, do we need both the driver name and the MTD name
to be the same? Or could we just stick the  "pxa3xx_nand-0" directly
in mtd->name only, where it's needed for compatibility, and allow the
driver name to be cleaner? Or is that a silly idea?

Brian


From ezequiel.garcia at free-electrons.com  Fri Oct 18 15:32:12 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 16:32:12 -0300
Subject: [PATCH v2] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <CAN8TOE-hxcaj79hTxDMzP1On69n=3QdBy45fjePLrQuzSvnnyw@mail.gmail.com>
References: <1382120072-30057-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAN8TOE-hxcaj79hTxDMzP1On69n=3QdBy45fjePLrQuzSvnnyw@mail.gmail.com>
Message-ID: <20131018193211.GA30464@localhost>

On Fri, Oct 18, 2013 at 12:15:39PM -0700, Brian Norris wrote:
> On Fri, Oct 18, 2013 at 11:14 AM, Ezequiel Garcia
> <ezequiel.garcia at free-electrons.com> wrote:
> > In a recent commit:
> >
> >   commit f455578dd961087a5cf94730d9f6489bb1d355f0
> >   Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> >   Date:   Mon Aug 12 14:14:53 2013 -0300
> >
> >   mtd: nand: pxa3xx: Remove hardcoded mtd name
> >
> >   There's no advantage in using a hardcoded name for the mtd device.
> >   Instead use the provided by the platform_device.
> >
> > The MTD name was changed to use the one provided by the platform_device.
> > However, this can be problematic as some users want to set partitions
> > using the kernel parameter 'mtdpart', where the name is needed.
> >
> > Therefore, to avoid regressions in users relying in 'mtdpart' we revert
> > the change and use the previous one 'pxa3xx_nand-0'.
> >
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> 
> Should this be marked for -stable (or squeezed into 3.12-rc now), so
> we don't leave the regression in 3.12?
> 

Yes, I think that if we're still on time to fix v3.12 it would be great.
(Sorry for taking care of my own crap so late!).

> > ---
> > v1->v2:
> >   * Use exactly the same name as before, and avoid regressions
> >     instead of using any seemingly better or cleaner one.
> >
> >  drivers/mtd/nand/pxa3xx_nand.c | 6 ++++--
> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> > index aa75adf..4d53e8e 100644
> > --- a/drivers/mtd/nand/pxa3xx_nand.c
> > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> > @@ -46,6 +46,8 @@
> >   */
> >  #define INIT_BUFFER_SIZE       256
> >
> > +#define DRIVER_NAME            "pxa3xx_nand-0"
> > +
> >  /* registers and bit definitions */
> >  #define NDCR           (0x00) /* Control register */
> >  #define NDTR0CS0       (0x04) /* Timing Parameter 0 for CS0 */
> > @@ -1339,7 +1341,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
> >         for (cs = 0; cs < pdata->num_cs; cs++) {
> >                 struct mtd_info *mtd = info->host[cs]->mtd;
> >
> > -               mtd->name = pdev->name;
> > +               mtd->name = DRIVER_NAME;
> >                 info->cs = cs;
> >                 ret = pxa3xx_nand_scan(mtd);
> >                 if (ret) {
> > @@ -1425,7 +1427,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
> >
> >  static struct platform_driver pxa3xx_nand_driver = {
> >         .driver = {
> > -               .name   = "pxa3xx-nand",
> > +               .name   = DRIVER_NAME,
> >                 .of_match_table = pxa3xx_nand_dt_ids,
> >         },
> >         .probe          = pxa3xx_nand_probe,
> 
> For mtdparts' sake, do we need both the driver name and the MTD name
> to be the same? Or could we just stick the  "pxa3xx_nand-0" directly
> in mtd->name only, where it's needed for compatibility, and allow the
> driver name to be cleaner? Or is that a silly idea?
> 

Hm... What's the impact of the driver's name?

I know it's just a small bloat, but still I don't like to see two stupid
strings "pxa3xx-nand" and "pxa3xx_nand-0" bloating our kernels, so
that's why I chose a common macro :-)

What do you think?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From tharvey at gateworks.com  Fri Oct 18 16:45:33 2013
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 18 Oct 2013 13:45:33 -0700
Subject: gpmi-mtd ecc regression
In-Reply-To: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
References: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
Message-ID: <CAJ+vNU0yDJcUaw5=6V1rFbecW3Y+6qOw40S3nJ4eeDwjZwdcCw@mail.gmail.com>

On Fri, Oct 18, 2013 at 10:03 AM, Tim Harvey <tharvey at gateworks.com> wrote:
> Huang,
>
> The patch you made to obtain ECC info from the chip
> (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/mtd/nand/gpmi-nand?id=2febcdf84b75aae627c61f0a5bf531a69299966c)
> has caused a regression for an i.MX6 board I'm working with that uses
> NAND and ubifs.
>
> I'm using a Micron MT29F8G08
> (http://download.micron.com/pdf/datasheets/flash/nand/2_4_8gb_nand_m49a.pdf)
> which has:
> page size: 2112 bytes (2048 + 64 bytes)
> block size: 1056 words (1024 + 32 words)
> plane size: 2 planes x 1024 blocks per plane
> device size: 2Gb: 2048 blocks
> ecc: 4bit
>
> The legacy_set_geometry function comes up with:
> gf_len=13
> ecc_strength=8
> page_size=2112
> metadata_size=10
> ecc_chunk_size=512
> ecc_chunk_count=4
> payload_size=2048
> auxiliary_size=16
> auxiliary_status_offset=12
> block_mark_byte_offset=1999
>
> and the new set_geometry_by_ecc_info comes up with:
> gf_len=13
> ecc_strength=4

digging more into the issue I believe the problem is that the 'chip'
has an internal 4-bit ECC which is now being used, whereas what we
want is the BCH's ECC to be used (which would use 8bit ECC with a NAND
device with a pagesize of 2048 + 64 OOB).  If I force ecc_stength such
as:

@@ -143,7 +143,7 @@ static bool set_geometry_by_ecc_info(struct
gpmi_nand_data *this)
                return false;
        }
        geo->ecc_chunk_size = chip->ecc_step_ds;
-       geo->ecc_strength = round_up(chip->ecc_strength_ds, 2);
+       geo->ecc_strength = 8;
        if (!gpmi_check_ecc(this))
                return false;

@@ -208,6 +208,7 @@ static bool set_geometry_by_ecc_info(struct
gpmi_nand_data *this)

then I have no issues.

Does this make sense and if so should we be using the chip's reported
ecc strength at all?

Tim


From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:31 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:31 -0300
Subject: [PATCH v2 04/27] ARM: mvebu: Add the core-divider clock to Armada
 370/XP
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-5-git-send-email-ezequiel.garcia@free-electrons.com>

The Armada 370/XP SoC has a clock provider called "Core Divider",
that is derived from a fixed 2 GHz PLL clock.

Reviewed-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/boot/dts/armada-370-xp.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 924c721..01e69fc 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -137,6 +137,14 @@
 				status = "disabled";
 			};
 
+			coredivclk: corediv-clock at 18740 {
+				compatible = "marvell,armada-370-corediv-clock";
+				reg = <0x18740 0xc>;
+				#clock-cells = <1>;
+				clocks = <&mainpll>;
+				clock-output-names = "nand";
+			};
+
 			timer at 20300 {
 				reg = <0x20300 0x30>, <0x21040 0x30>;
 				interrupts = <37>, <38>, <39>, <40>, <5>, <6>;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:30 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:30 -0300
Subject: [PATCH v2 03/27] ARM: mvebu: Add a 2 GHz fixed-clock Armada 370/XP
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-4-git-send-email-ezequiel.garcia@free-electrons.com>

Armada 370/XP SoCs have a 2 GHz fixed PLL that is used to feed
other clocks. This commit adds a DT representation of this clock
through a fixed-clock compatible node.

Reviewed-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/boot/dts/armada-370-xp.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 1de2dae..924c721 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -252,4 +252,13 @@
 
 		};
 	};
+
+	clocks {
+		/* 2 GHz fixed main PLL */
+		mainpll: mainpll {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <2000000000>;
+		};
+	};
  };
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:29 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:29 -0300
Subject: [PATCH v2 02/27] ARM: mvebu: Add Core Divider clock device-tree
 binding
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-3-git-send-email-ezequiel.garcia@free-electrons.com>

The Armada 370/XP SoCs have a Core Divider clock providing
several clocks. For now, only the NAND clock is supported.

Reviewed-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 .../devicetree/bindings/clock/mvebu-corediv-clock.txt | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt

diff --git a/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
new file mode 100644
index 0000000..c62391f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
@@ -0,0 +1,19 @@
+* Core Divider Clock bindings for Marvell MVEBU SoCs
+
+The following is a list of provided IDs and clock names on Armada 370/XP:
+ 0 = nand (NAND clock)
+
+Required properties:
+- compatible : must be "marvell,armada-370-corediv-clock"
+- reg : must be the register address of Core Divider control register
+- #clock-cells : from common clock binding; shall be set to 1
+- clocks : must be set to the parent's phandle
+
+Example:
+
+corediv_clk: corediv-clocks at 18740 {
+	compatible = "marvell,armada-370-corediv-clock";
+	reg = <0x18740 0xc>;
+	#clock-cells = <1>;
+	clocks = <&pll>;
+};
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:28 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:28 -0300
Subject: [PATCH v2 01/27] clk: mvebu: Add Core Divider clock
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-2-git-send-email-ezequiel.garcia@free-electrons.com>

This commit introduces a new group of clocks present in Armada 370/XP
SoCs (called "Core Divider" clocks) and add a provider for them.
The only clock supported for now is the NAND clock (ndclk), but the
infrastructure to add the rest is already set.

Reviewed-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
Acked-by: Jason Cooper <jason at lakedaemon.net>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/clk/mvebu/Kconfig       |   5 +
 drivers/clk/mvebu/Makefile      |   1 +
 drivers/clk/mvebu/clk-corediv.c | 223 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 229 insertions(+)
 create mode 100644 drivers/clk/mvebu/clk-corediv.c

diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
index 0b0f3e7..c339b82 100644
--- a/drivers/clk/mvebu/Kconfig
+++ b/drivers/clk/mvebu/Kconfig
@@ -4,15 +4,20 @@ config MVEBU_CLK_COMMON
 config MVEBU_CLK_CPU
 	bool
 
+config MVEBU_CLK_COREDIV
+	bool
+
 config ARMADA_370_CLK
 	bool
 	select MVEBU_CLK_COMMON
 	select MVEBU_CLK_CPU
+	select MVEBU_CLK_COREDIV
 
 config ARMADA_XP_CLK
 	bool
 	select MVEBU_CLK_COMMON
 	select MVEBU_CLK_CPU
+	select MVEBU_CLK_COREDIV
 
 config DOVE_CLK
 	bool
diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
index 1c7e70c..21bbfb4 100644
--- a/drivers/clk/mvebu/Makefile
+++ b/drivers/clk/mvebu/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_MVEBU_CLK_COMMON)	+= common.o
 obj-$(CONFIG_MVEBU_CLK_CPU) 	+= clk-cpu.o
+obj-$(CONFIG_MVEBU_CLK_COREDIV)	+= clk-corediv.o
 
 obj-$(CONFIG_ARMADA_370_CLK)	+= armada-370.o
 obj-$(CONFIG_ARMADA_XP_CLK)	+= armada-xp.o
diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c
new file mode 100644
index 0000000..7162615
--- /dev/null
+++ b/drivers/clk/mvebu/clk-corediv.c
@@ -0,0 +1,223 @@
+/*
+ * MVEBU Core divider clock
+ *
+ * Copyright (C) 2013 Marvell
+ *
+ * Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "common.h"
+
+#define CORE_CLK_DIV_RATIO_MASK		0xff
+#define CORE_CLK_DIV_RATIO_RELOAD	BIT(8)
+#define CORE_CLK_DIV_ENABLE_OFFSET	24
+#define CORE_CLK_DIV_RATIO_OFFSET	0x8
+
+struct clk_corediv_desc {
+	unsigned int mask;
+	unsigned int offset;
+	unsigned int fieldbit;
+};
+
+struct clk_corediv {
+	struct clk_hw hw;
+	void __iomem *reg;
+	struct clk_corediv_desc desc;
+	spinlock_t lock;
+};
+
+static struct clk_onecell_data clk_data;
+
+static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
+	{ .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
+};
+
+#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
+
+static int clk_corediv_is_enabled(struct clk_hw *hwclk)
+{
+	struct clk_corediv *corediv = to_corediv_clk(hwclk);
+	struct clk_corediv_desc *desc = &corediv->desc;
+	u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET;
+
+	return !!(readl(corediv->reg) & enable_mask);
+}
+
+static int clk_corediv_enable(struct clk_hw *hwclk)
+{
+	struct clk_corediv *corediv = to_corediv_clk(hwclk);
+	struct clk_corediv_desc *desc = &corediv->desc;
+	unsigned long flags = 0;
+	u32 reg;
+
+	spin_lock_irqsave(&corediv->lock, flags);
+
+	reg = readl(corediv->reg);
+	reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+	writel(reg, corediv->reg);
+
+	spin_unlock_irqrestore(&corediv->lock, flags);
+
+	return 0;
+}
+
+static void clk_corediv_disable(struct clk_hw *hwclk)
+{
+	struct clk_corediv *corediv = to_corediv_clk(hwclk);
+	struct clk_corediv_desc *desc = &corediv->desc;
+	unsigned long flags = 0;
+	u32 reg;
+
+	spin_lock_irqsave(&corediv->lock, flags);
+
+	reg = readl(corediv->reg);
+	reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
+	writel(reg, corediv->reg);
+
+	spin_unlock_irqrestore(&corediv->lock, flags);
+}
+
+static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
+					 unsigned long parent_rate)
+{
+	struct clk_corediv *corediv = to_corediv_clk(hwclk);
+	struct clk_corediv_desc *desc = &corediv->desc;
+	u32 reg, div;
+
+	reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+	div = (reg >> desc->offset) & desc->mask;
+	return parent_rate / div;
+}
+
+static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
+			       unsigned long *parent_rate)
+{
+	/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
+	u32 div;
+
+	div = *parent_rate / rate;
+	if (div < 4)
+		div = 4;
+	else if (div > 6)
+		div = 8;
+
+	return *parent_rate / div;
+}
+
+static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct clk_corediv *corediv = to_corediv_clk(hwclk);
+	struct clk_corediv_desc *desc = &corediv->desc;
+	unsigned long flags = 0;
+	u32 reg, div;
+
+	div = parent_rate / rate;
+
+	spin_lock_irqsave(&corediv->lock, flags);
+
+	/* Write new divider to the divider ratio register */
+	reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+	reg &= ~(desc->mask << desc->offset);
+	reg |= (div & desc->mask) << desc->offset;
+	writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
+
+	/* Set reload-force for this clock */
+	reg = readl(corediv->reg) | BIT(desc->fieldbit);
+	writel(reg, corediv->reg);
+
+	/* Now trigger the clock update */
+	reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD;
+	writel(reg, corediv->reg);
+
+	/*
+	 * Wait for clocks to settle down, and then clear all the
+	 * ratios request and the reload request.
+	 */
+	udelay(1000);
+	reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD);
+	writel(reg, corediv->reg);
+	udelay(1000);
+
+	spin_unlock_irqrestore(&corediv->lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops corediv_ops = {
+	.enable = clk_corediv_enable,
+	.disable = clk_corediv_disable,
+	.is_enabled = clk_corediv_is_enabled,
+	.recalc_rate = clk_corediv_recalc_rate,
+	.round_rate = clk_corediv_round_rate,
+	.set_rate = clk_corediv_set_rate,
+};
+
+static void __init mvebu_corediv_clk_init(struct device_node *node)
+{
+	struct clk_init_data init;
+	struct clk_corediv *corediv;
+	struct clk **clks;
+	void __iomem *base;
+	const char *parent_name;
+	const char *clk_name;
+	int i;
+
+	base = of_iomap(node, 0);
+	if (WARN_ON(!base))
+		return;
+
+	parent_name = of_clk_get_parent_name(node, 0);
+
+	clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc);
+
+	/* clks holds the clock array */
+	clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
+				GFP_KERNEL);
+	if (WARN_ON(!clks))
+		goto err_unmap;
+	/* corediv holds the clock specific array */
+	corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),
+				GFP_KERNEL);
+	if (WARN_ON(!corediv))
+		goto err_free_clks;
+
+	spin_lock_init(&corediv->lock);
+
+	for (i = 0; i < clk_data.clk_num; i++) {
+		of_property_read_string_index(node, "clock-output-names",
+					      i, &clk_name);
+		init.num_parents = 1;
+		init.parent_names = &parent_name;
+		init.name = clk_name;
+		init.ops = &corediv_ops;
+		init.flags = 0;
+
+		corediv[i].desc = mvebu_corediv_desc[i];
+		corediv[i].reg = base;
+		corediv[i].hw.init = &init;
+
+		clks[i] = clk_register(NULL, &corediv[i].hw);
+		WARN_ON(IS_ERR(clks[i]));
+	}
+
+	clk_data.clks = clks;
+	of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
+	return;
+
+err_free_clks:
+	kfree(clks);
+err_unmap:
+	iounmap(base);
+}
+CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock",
+	       mvebu_corediv_clk_init);
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:27 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:27 -0300
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
Message-ID: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>

Hi guys,

This is the v2 of the work implementing NAND support in Armada 370/XP SoCs.
This series is probably not yet complete (see below), but I feel like
we're really closer now :-)

As in the previous version and given I don't have any public datasheet
to show, I'll try to write some of the most relevant parts of the controller.

* NFCv2 controller background

The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
chunked transfers.

For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
we'll have this layout in the pages:

  ------------------------------------------------------------------------------
  | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
  ------------------------------------------------------------------------------

The driver reads the data and spare portions independently and builds an internal
buffer with this layout (in the 4 KiB page case):

  ------------------------------------------
  |     4096B data     |     64B spare     |
  ------------------------------------------

Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
OOB, one per chunk read.

  -------------------------------------------------------------------
  |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC |
  -------------------------------------------------------------------

So, in order to achieve reading (for instance), we issue several READ0 commands
(with some additional controller-specific magic) and read two chunks of 2080B
(2048 data + 32 spare) each.
The driver accomodates this data to expose the NAND core a contiguous buffer
(4096 data + spare) or (4096 + spare + ECC + spare + ECC).

* ECC

The controller has built-in hardware ECC capabilities. In addition it is
configurable between two modes: 1) Hamming, 2) BCH.

Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
the controller is configured to transfer the data.

In the BCH mode the ECC code will be calculated for each transfered chunk
and expected to be located (when reading/programming) right after the spare
bytes as the figure above shows.

So, repeating the above scheme, a 2048B data chunk will be followed by 32B
spare, and then the ECC controller will read/write the ECC code (30B in
this case):

  ------------------------------------
  | 2048B data | 32B spare | 30B ECC |
  ------------------------------------

If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
So in Hamming mode, a 2048B page will have a 24B ECC.

Despite all of the above, the controller requires the driver to only read or
write in multiples of 8-bytes, because the data buffer is 64-bits.

* Changes from v1

Aside from several changes based in Brian's feedback, the main changes
from v1 are:

  * The controller's clock source is now fully modeled, see patche 1 to 4.
    Of course, none of those patches should be taken through the mtd
    subsystem, but I'm adding them here for completeness.

  * The chip's cmdfunc() is now independently implemented in each SoC variant.
    The rationale behind this decision is that 'chunked' I/O is the only tested
    mode on the Armada370 variant, while the old 'vanilla' I/O is the only
    tested mode on the PXA variant.

    So it's safer to have an implementation for each variant.

  * Added support for BCH-8, in other words: 8-bits of correction in a 512-byte
    region. This is obtained by using a data chunk size of 1024B, thus doubling
    the ECC BCH strength, as per this ECC engine mechanism.

  * The ECC layout in use, which must be set according to the page size and
    desired ECC strength is now strictly chosen to match only the tested
    combinations.

* Pending stuff

  1. Factory bad blocks handling

  Currently, there's no factory bad block initial scan (when the bad block
  table is missing). The ECC BCH requires to layout the device's pages in
  a splitted "data + OOB + data + OOB" way. This layout being different from
  the factory layout. In other words,

  Factory view:

  -----------------------------------------------
  |                    Data           |x  OOB   |
  -----------------------------------------------

  Driver's view:

  -----------------------------------------------
  |      Data      | OOB |      Data   x  | OOB |
  -----------------------------------------------

  It can be seen from the above, that the factory bad block marker must be
  searched within the 'data' region, and not in the usual OOB region.

  This seems to be similar to the gpmi-nand driver, yet I really find its
  'bad block swapping' solution odd, so I'm trying to find something
  cleaner.

  2. ECC modeling

  Although I've exposed some ECC information in the ECC layout, I'm still
  not sure why is this needed, or if it's needed at all.

* About this patchset

This is based in l2-mtd's master branch and I've pushed a branch to our
github in case anyone wants to test it:

  https://github.com/MISL-EBU-System-SW/mainline-public/tree/l2-mtd/upstream-nand-v2

Just as the previous, this series is complex and lengthy and any feedback will
be highly appreciated as well as questions, suggestions or flames. Also, I hope
our brave PXA regression tester Daniel Mack finds some time to give it a ride
and report any issues. Daniel: I think owe you several beers already.

* About Mirabox testing

As this work is not considered completely stable, be extra careful when trying
on the Mirabox. The Mirabox has the bootloader at NAND, and there's some risk
to brick the board.

That said: I've been using the driver on my Mirabox for several days doing
simple long-run NAND activity and everything worked fine.

If despite this you happen to brick the board, Willy Tarreau has provided
excellent instructions to un-brick the Mirabox:

  http://1wt.eu/articles/mirabox-vs-guruplug/

Thanks!

Ezequiel Garcia (27):
  clk: mvebu: Add Core Divider clock
  ARM: mvebu: Add Core Divider clock device-tree binding
  ARM: mvebu: Add a 2 GHz fixed-clock Armada 370/XP
  ARM: mvebu: Add the core-divider clock to Armada 370/XP
  mtd: nand: pxa3xx: Make config menu show supported platforms
  mtd: nand: pxa3xx: Prevent sub-page writes
  mtd: nand: pxa3xx: Early variant detection
  mtd: nand: pxa3xx: Use chip->cmdfunc instead of the internal
  mtd: nand: pxa3xx: Split FIFO size from to-be-read FIFO count
  mtd: nand: pxa3xx: Replace host->page_size by mtd->writesize
  mtd: nand: pxa3xx: Disable OOB on arbitrary length commands
  mtd: nand: pxa3xx: Use a completion to signal device ready
  mtd: nand: pxa3xx: Add bad block handling
  mtd: nand: pxa3xx: Add driver-specific ECC BCH support
  mtd: nand: pxa3xx: Clear cmd buffer #3 (NDCB3) on command start
  mtd: nand: pxa3xx: Add helper function to set page address
  mtd: nand: pxa3xx: Remove READ0 switch/case falltrough
  mtd: nand: pxa3xx: Split prepare_command_pool() in two stages
  mtd: nand: pxa3xx: Move the data buffer clean to
    prepare_start_command()
  mtd: nand: pxa3xx: Fix SEQIN column address set
  mtd: nand: pxa3xx: Add a read/write buffers markers
  mtd: nand: pxa3xx: Introduce multiple page I/O support
  mtd: nand: pxa3xx: Add multiple chunk write support
  mtd: nand: pxa3xx: Add ECC BCH correctable errors detection
  ARM: mvebu: Add support for NAND controller in Armada 370/XP
  ARM: mvebu: Enable NAND controller in Armada XP GP board
  ARM: mvebu: Enable NAND controller in Armada 370 Mirabox

 .../bindings/clock/mvebu-corediv-clock.txt         |  19 +
 arch/arm/boot/dts/armada-370-mirabox.dts           |  21 +
 arch/arm/boot/dts/armada-370-xp.dtsi               |  26 +
 arch/arm/boot/dts/armada-xp-gp.dts                 |   8 +
 drivers/clk/mvebu/Kconfig                          |   5 +
 drivers/clk/mvebu/Makefile                         |   1 +
 drivers/clk/mvebu/clk-corediv.c                    | 223 +++++++
 drivers/mtd/nand/Kconfig                           |   4 +-
 drivers/mtd/nand/pxa3xx_nand.c                     | 686 ++++++++++++++++-----
 include/linux/platform_data/mtd-nand-pxa3xx.h      |   3 +
 10 files changed, 856 insertions(+), 140 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
 create mode 100644 drivers/clk/mvebu/clk-corediv.c

-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:32 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:32 -0300
Subject: [PATCH v2 05/27] mtd: nand: pxa3xx: Make config menu show supported
 platforms
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-6-git-send-email-ezequiel.garcia@free-electrons.com>

Since we have now support for the NFCv2 controller found on
Armada 370/XP platforms.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..791d219 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -354,11 +354,11 @@ config MTD_NAND_ATMEL
 	  on Atmel AT91 and AVR32 processors.
 
 config MTD_NAND_PXA3xx
-	tristate "Support for NAND flash devices on PXA3xx"
+	tristate "NAND support on PXA3xx and Armada 370/XP"
 	depends on PXA3xx || ARCH_MMP || PLAT_ORION
 	help
 	  This enables the driver for the NAND flash device found on
-	  PXA3xx processors
+	  PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
 
 config MTD_NAND_SLC_LPC32XX
 	tristate "NXP LPC32xx SLC Controller"
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:33 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:33 -0300
Subject: [PATCH v2 06/27] mtd: nand: pxa3xx: Prevent sub-page writes
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-7-git-send-email-ezequiel.garcia@free-electrons.com>

The current driver doesn't support sub-page writing, so report
that to the NAND core.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index aa75adf..5ca3154 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1143,6 +1143,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
 		chip->read_byte		= pxa3xx_nand_read_byte;
 		chip->read_buf		= pxa3xx_nand_read_buf;
 		chip->write_buf		= pxa3xx_nand_write_buf;
+		chip->options		|= NAND_NO_SUBPAGE_WRITE;
 	}
 
 	spin_lock_init(&chip->controller->lock);
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:36 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:36 -0300
Subject: [PATCH v2 09/27] mtd: nand: pxa3xx: Split FIFO size from to-be-read
 FIFO count
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-10-git-send-email-ezequiel.garcia@free-electrons.com>

Introduce a fifo_size field to represent the size of the controller's
FIFO buffer, and use it to distinguish that size from the amount
of data bytes to be read from the FIFO.

This is important to support devices with pages larger than the
controller's internal FIFO, that need to read the pages in FIFO-sized
chunks.

In particular, the current code is at least confusing, for it mixes
all the different sizes involved: FIFO size, page size and data size.

This commit starts the cleaning by removing the info->page_size field
that is not currently used. The host->page_size field should also
be removed and use always mtd->writesize instead. Follow up commits
will clean this up.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 1e2f4ae..fe2e27c 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -199,8 +199,8 @@ struct pxa3xx_nand_info {
 	int			use_spare;	/* use spare ? */
 	int			is_ready;
 
-	unsigned int		page_size;	/* page size of attached chip */
-	unsigned int		data_size;	/* data size in FIFO */
+	unsigned int		fifo_size;	/* max. data size in the FIFO */
+	unsigned int		data_size;	/* data to be read from FIFO */
 	unsigned int		oob_size;
 	int 			retcode;
 
@@ -305,16 +305,15 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
 
 static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 {
-	struct pxa3xx_nand_host *host = info->host[info->cs];
 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
 
-	info->data_size = host->page_size;
+	info->data_size = info->fifo_size;
 	if (!oob_enable) {
 		info->oob_size = 0;
 		return;
 	}
 
-	switch (host->page_size) {
+	switch (info->fifo_size) {
 	case 2048:
 		info->oob_size = (info->use_ecc) ? 40 : 64;
 		break;
@@ -929,9 +928,12 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 	uint32_t ndcr = nand_readl(info, NDCR);
 
 	if (ndcr & NDCR_PAGE_SZ) {
+		/* Controller's FIFO size */
+		info->fifo_size = 2048;
 		host->page_size = 2048;
 		host->read_id_bytes = 4;
 	} else {
+		info->fifo_size = 512;
 		host->page_size = 512;
 		host->read_id_bytes = 2;
 	}
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:34 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:34 -0300
Subject: [PATCH v2 07/27] mtd: nand: pxa3xx: Early variant detection
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-8-git-send-email-ezequiel.garcia@free-electrons.com>

In order to customize early settings depending on the detected SoC variant,
move the detection to be before the nand_chip struct filling.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 48 +++++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 5ca3154..83ea806 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -256,6 +256,29 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
 /* convert nano-seconds to nand flash controller clock cycles */
 #define ns2cycle(ns, clk)	(int)((ns) * (clk / 1000000) / 1000)
 
+static struct of_device_id pxa3xx_nand_dt_ids[] = {
+	{
+		.compatible = "marvell,pxa3xx-nand",
+		.data       = (void *)PXA3XX_NAND_VARIANT_PXA,
+	},
+	{
+		.compatible = "marvell,armada370-nand",
+		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
+
+static enum pxa3xx_nand_variant
+pxa3xx_nand_get_variant(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id =
+			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
+	if (!of_id)
+		return PXA3XX_NAND_VARIANT_PXA;
+	return (enum pxa3xx_nand_variant)of_id->data;
+}
+
 static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
 				   const struct pxa3xx_nand_timing *t)
 {
@@ -1121,6 +1144,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
 		return -ENOMEM;
 
 	info->pdev = pdev;
+	info->variant = pxa3xx_nand_get_variant(pdev);
 	for (cs = 0; cs < pdata->num_cs; cs++) {
 		mtd = (struct mtd_info *)((unsigned int)&info[1] +
 		      (sizeof(*mtd) + sizeof(*host)) * cs);
@@ -1256,29 +1280,6 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct of_device_id pxa3xx_nand_dt_ids[] = {
-	{
-		.compatible = "marvell,pxa3xx-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_PXA,
-	},
-	{
-		.compatible = "marvell,armada370-nand",
-		.data       = (void *)PXA3XX_NAND_VARIANT_ARMADA370,
-	},
-	{}
-};
-MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids);
-
-static enum pxa3xx_nand_variant
-pxa3xx_nand_get_variant(struct platform_device *pdev)
-{
-	const struct of_device_id *of_id =
-			of_match_device(pxa3xx_nand_dt_ids, &pdev->dev);
-	if (!of_id)
-		return PXA3XX_NAND_VARIANT_PXA;
-	return (enum pxa3xx_nand_variant)of_id->data;
-}
-
 static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
 {
 	struct pxa3xx_nand_platform_data *pdata;
@@ -1335,7 +1336,6 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 	}
 
 	info = platform_get_drvdata(pdev);
-	info->variant = pxa3xx_nand_get_variant(pdev);
 	probe_success = 0;
 	for (cs = 0; cs < pdata->num_cs; cs++) {
 		struct mtd_info *mtd = info->host[cs]->mtd;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:37 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:37 -0300
Subject: [PATCH v2 10/27] mtd: nand: pxa3xx: Replace host->page_size by
 mtd->writesize
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-11-git-send-email-ezequiel.garcia@free-electrons.com>

There's no need to privately store the device page size as it's
available in mtd structure field mtd->writesize.
Also, this removes the hardcoded page size value, leaving the
auto-detected value only.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index fe2e27c..83ba036 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -149,7 +149,6 @@ struct pxa3xx_nand_host {
 	void			*info_data;
 
 	/* page size of attached chip */
-	unsigned int		page_size;
 	int			use_ecc;
 	int			cs;
 
@@ -612,12 +611,12 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 			info->buf_start += mtd->writesize;
 
 		/* Second command setting for large pages */
-		if (host->page_size >= PAGE_CHUNK_SIZE)
+		if (mtd->writesize >= PAGE_CHUNK_SIZE)
 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
 
 	case NAND_CMD_SEQIN:
 		/* small page addr setting */
-		if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) {
+		if (unlikely(mtd->writesize < PAGE_CHUNK_SIZE)) {
 			info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
 					| (column & 0xFF);
 
@@ -891,7 +890,6 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
 	}
 
 	/* calculate flash information */
-	host->page_size = f->page_size;
 	host->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
 
 	/* calculate addressing information */
@@ -930,11 +928,9 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 	if (ndcr & NDCR_PAGE_SZ) {
 		/* Controller's FIFO size */
 		info->fifo_size = 2048;
-		host->page_size = 2048;
 		host->read_id_bytes = 4;
 	} else {
 		info->fifo_size = 512;
-		host->page_size = 512;
 		host->read_id_bytes = 2;
 	}
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:35 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:35 -0300
Subject: [PATCH v2 08/27] mtd: nand: pxa3xx: Use chip->cmdfunc instead of the
 internal
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-9-git-send-email-ezequiel.garcia@free-electrons.com>

Whenever possible, it's always better to use the generic chip->cmdfunc
instead of the internal pxa3xx_nand_cmdfunc().
In this particular case, this will allow to have multiple cmdfunc()
implementations for different SoC variants.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 83ea806..1e2f4ae 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1011,14 +1011,16 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info)
 static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
 {
 	struct mtd_info *mtd;
+	struct nand_chip *chip;
 	int ret;
 	mtd = info->host[info->cs]->mtd;
+	chip = mtd->priv;
 	/* use the common timing to make a try */
 	ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]);
 	if (ret)
 		return ret;
 
-	pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
+	chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
 	if (info->is_ready)
 		return 0;
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:38 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:38 -0300
Subject: [PATCH v2 11/27] mtd: nand: pxa3xx: Disable OOB on arbitrary length
 commands
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-12-git-send-email-ezequiel.garcia@free-electrons.com>

READID, STATUS and PARAM (aka ONFI read paramater page) don't read
the OOB area. Set the oob_size to zero and prevent it.
Also, add a comment clarifying the use of pxa3xx_set_datasize()
which is only applicable on data read/write commands.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 83ba036..95e2ce3 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -302,6 +302,11 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
 	nand_writel(info, NDTR1CS0, ndtr1);
 }
 
+/*
+ * Set the data and OOB size, depending on the selected
+ * spare and ECC configuration.
+ * Only applicable to READ0, READOOB and PAGEPROG commands.
+ */
 static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 {
 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
@@ -661,6 +666,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 		info->ndcb1 = (column & 0xFF);
 		info->ndcb3 = 256;
 		info->data_size = 256;
+		info->oob_size = 0;
 		break;
 
 	case NAND_CMD_READID:
@@ -671,6 +677,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 		info->ndcb1 = (column & 0xFF);
 
 		info->data_size = 8;
+		info->oob_size = 0;
 		break;
 	case NAND_CMD_STATUS:
 		info->buf_count = 1;
@@ -679,6 +686,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 				| command;
 
 		info->data_size = 8;
+		info->oob_size = 0;
 		break;
 
 	case NAND_CMD_ERASE1:
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:43 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:43 -0300
Subject: [PATCH v2 16/27] mtd: nand: pxa3xx: Add helper function to set page
 address
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-17-git-send-email-ezequiel.garcia@free-electrons.com>

Let's simplify the code by first introducing a helper function
to set the page address, as done by the READ0, READOOB and SEQIN
commands.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 36 +++++++++++++++++++++---------------
 1 file changed, 21 insertions(+), 15 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index be90304..e9d0dde 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -592,6 +592,26 @@ static inline int is_buf_blank(uint8_t *buf, size_t len)
 	return 1;
 }
 
+static void set_command_address(struct pxa3xx_nand_info *info,
+		unsigned int page_size, uint16_t column, int page_addr)
+{
+	/* small page addr setting */
+	if (page_size < PAGE_CHUNK_SIZE) {
+		info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
+				| (column & 0xFF);
+
+		info->ndcb2 = 0;
+	} else {
+		info->ndcb1 = ((page_addr & 0xFFFF) << 16)
+				| (column & 0xFFFF);
+
+		if (page_addr & 0xFF0000)
+			info->ndcb2 = (page_addr & 0xFF0000) >> 16;
+		else
+			info->ndcb2 = 0;
+	}
+}
+
 static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 		uint16_t column, int page_addr)
 {
@@ -655,22 +675,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
 
 	case NAND_CMD_SEQIN:
-		/* small page addr setting */
-		if (unlikely(mtd->writesize < PAGE_CHUNK_SIZE)) {
-			info->ndcb1 = ((page_addr & 0xFFFFFF) << 8)
-					| (column & 0xFF);
-
-			info->ndcb2 = 0;
-		} else {
-			info->ndcb1 = ((page_addr & 0xFFFF) << 16)
-					| (column & 0xFFFF);
-
-			if (page_addr & 0xFF0000)
-				info->ndcb2 = (page_addr & 0xFF0000) >> 16;
-			else
-				info->ndcb2 = 0;
-		}
 
+		set_command_address(info, mtd->writesize, column, page_addr);
 		info->buf_count = mtd->writesize + mtd->oobsize;
 		memset(info->data_buff, 0xFF, info->buf_count);
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:39 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:39 -0300
Subject: [PATCH v2 12/27] mtd: nand: pxa3xx: Use a completion to signal device
 ready
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-13-git-send-email-ezequiel.garcia@free-electrons.com>

Apparently, the expected behavior of the waitfunc() NAND chip call
is to wait for the device to be READY (this is a standard chip line).
However, the current implementation does almost nothing, which opens
a possibility to issue a command to a non-ready device.

Fix this by adding a new completion to wait for the ready event to arrive.

Because the "is ready" flag is cleared from the controller status
register, it's needed to store that state in the driver, and because the
field is accesed from an interruption, the field needs to be of an
atomic type.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 45 +++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 95e2ce3..1ceccb6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -35,6 +35,7 @@
 
 #include <linux/platform_data/mtd-nand-pxa3xx.h>
 
+#define NAND_DEV_READY_TIMEOUT  50
 #define	CHIP_DELAY_TIMEOUT	(2 * HZ/10)
 #define NAND_STOP_DELAY		(2 * HZ/50)
 #define PAGE_CHUNK_SIZE		(2048)
@@ -166,7 +167,7 @@ struct pxa3xx_nand_info {
 	struct clk		*clk;
 	void __iomem		*mmio_base;
 	unsigned long		mmio_phys;
-	struct completion	cmd_complete;
+	struct completion	cmd_complete, dev_ready;
 
 	unsigned int 		buf_start;
 	unsigned int		buf_count;
@@ -196,7 +197,13 @@ struct pxa3xx_nand_info {
 	int			use_ecc;	/* use HW ECC ? */
 	int			use_dma;	/* use DMA ? */
 	int			use_spare;	/* use spare ? */
-	int			is_ready;
+
+	/*
+	 * The is_ready flag is accesed from several places,
+	 * including an interruption hander. We need an atomic
+	 * type to avoid races.
+	 */
+	atomic_t		is_ready;
 
 	unsigned int		fifo_size;	/* max. data size in the FIFO */
 	unsigned int		data_size;	/* data to be read from FIFO */
@@ -478,7 +485,7 @@ static void start_data_dma(struct pxa3xx_nand_info *info)
 static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 {
 	struct pxa3xx_nand_info *info = devid;
-	unsigned int status, is_completed = 0;
+	unsigned int status, is_completed = 0, is_ready = 0;
 	unsigned int ready, cmd_done;
 
 	if (info->cs == 0) {
@@ -514,8 +521,9 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 		is_completed = 1;
 	}
 	if (status & ready) {
-		info->is_ready = 1;
+		atomic_set(&info->is_ready, 1);
 		info->state = STATE_READY;
+		is_ready = 1;
 	}
 
 	if (status & NDSR_WRCMDREQ) {
@@ -544,6 +552,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 	nand_writel(info, NDSR, status);
 	if (is_completed)
 		complete(&info->cmd_complete);
+	if (is_ready)
+		complete(&info->dev_ready);
 NORMAL_IRQ_EXIT:
 	return IRQ_HANDLED;
 }
@@ -574,7 +584,6 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 	info->oob_size		= 0;
 	info->use_ecc		= 0;
 	info->use_spare		= 1;
-	info->is_ready		= 0;
 	info->retcode		= ERR_NONE;
 	if (info->cs != 0)
 		info->ndcb0 = NDCB0_CSEL;
@@ -750,6 +759,8 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
 	exec_cmd = prepare_command_pool(info, command, column, page_addr);
 	if (exec_cmd) {
 		init_completion(&info->cmd_complete);
+		init_completion(&info->dev_ready);
+		atomic_set(&info->is_ready, 0);
 		pxa3xx_nand_start(info);
 
 		ret = wait_for_completion_timeout(&info->cmd_complete,
@@ -862,21 +873,27 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this)
 {
 	struct pxa3xx_nand_host *host = mtd->priv;
 	struct pxa3xx_nand_info *info = host->info_data;
+	int ret;
+
+	/* Need to wait? */
+	if (!atomic_read(&info->is_ready)) {
+		ret = wait_for_completion_timeout(&info->dev_ready,
+				CHIP_DELAY_TIMEOUT);
+		if (!ret) {
+			dev_err(&info->pdev->dev, "Ready time out!!!\n");
+			return NAND_STATUS_FAIL;
+		}
+	}
 
 	/* pxa3xx_nand_send_command has waited for command complete */
 	if (this->state == FL_WRITING || this->state == FL_ERASING) {
 		if (info->retcode == ERR_NONE)
 			return 0;
-		else {
-			/*
-			 * any error make it return 0x01 which will tell
-			 * the caller the erase and write fail
-			 */
-			return 0x01;
-		}
+		else
+			return NAND_STATUS_FAIL;
 	}
 
-	return 0;
+	return NAND_STATUS_READY;
 }
 
 static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
@@ -1027,7 +1044,7 @@ static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
 		return ret;
 
 	chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0);
-	if (info->is_ready)
+	if (atomic_read(&info->is_ready))
 		return 0;
 
 	return -ENODEV;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:44 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:44 -0300
Subject: [PATCH v2 17/27] mtd: nand: pxa3xx: Remove READ0 switch/case
 falltrough
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-18-git-send-email-ezequiel.garcia@free-electrons.com>

READ0 and READOOB command preparation has a falltrough to SEQIN
case, where the command address is specified.
This is certainly confusing and makes the code less readable with
no added value. Let's remove it.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index e9d0dde..cc5bcd1 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -674,6 +674,11 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 		if (mtd->writesize >= PAGE_CHUNK_SIZE)
 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
 
+		set_command_address(info, mtd->writesize, column, page_addr);
+		info->buf_count = mtd->writesize + mtd->oobsize;
+		memset(info->data_buff, 0xFF, info->buf_count);
+		break;
+
 	case NAND_CMD_SEQIN:
 
 		set_command_address(info, mtd->writesize, column, page_addr);
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:40 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:40 -0300
Subject: [PATCH v2 13/27] mtd: nand: pxa3xx: Add bad block handling
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-14-git-send-email-ezequiel.garcia@free-electrons.com>

Add support for flash-based bad block table using Marvell's
custom in-flash bad block table layout. The support is enabled
a 'flash_bbt' platform data or device tree parameter.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c                | 33 +++++++++++++++++++++++++++
 include/linux/platform_data/mtd-nand-pxa3xx.h |  3 +++
 2 files changed, 36 insertions(+)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 1ceccb6..451ebb6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 
 #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
 #define ARCH_HAS_DMA
@@ -245,6 +246,29 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = {
 { "256MiB 16-bit", 0xba20,  64, 2048, 16, 16, 2048, &timing[3] },
 };
 
+static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' };
+static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+		| NAND_BBT_2BIT | NAND_BBT_VERSION,
+	.offs =	8,
+	.len = 6,
+	.veroffs = 14,
+	.maxblocks = 8,		/* Last 8 blocks in each chip */
+	.pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+		| NAND_BBT_2BIT | NAND_BBT_VERSION,
+	.offs =	8,
+	.len = 6,
+	.veroffs = 14,
+	.maxblocks = 8,		/* Last 8 blocks in each chip */
+	.pattern = bbt_mirror_pattern
+};
+
 /* Define a default flash type setting serve as flash detecting only */
 #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
 
@@ -1129,6 +1153,14 @@ KEEP_CONFIG:
 
 	if (nand_scan_ident(mtd, 1, def))
 		return -ENODEV;
+
+	if (pdata->flash_bbt) {
+		chip->bbt_options |= NAND_BBT_USE_FLASH |
+				     NAND_BBT_NO_OOB_BBM;
+		chip->bbt_td = &bbt_main_descr;
+		chip->bbt_md = &bbt_mirror_descr;
+	}
+
 	/* calculate addressing information */
 	if (mtd->writesize >= 2048)
 		host->col_addr_cycles = 2;
@@ -1324,6 +1356,7 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
 	if (of_get_property(np, "marvell,nand-keep-config", NULL))
 		pdata->keep_config = 1;
 	of_property_read_u32(np, "num-cs", &pdata->num_cs);
+	pdata->flash_bbt = of_get_nand_on_flash_bbt(np);
 
 	pdev->dev.platform_data = pdata;
 
diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h
index ffb8019..a941471 100644
--- a/include/linux/platform_data/mtd-nand-pxa3xx.h
+++ b/include/linux/platform_data/mtd-nand-pxa3xx.h
@@ -55,6 +55,9 @@ struct pxa3xx_nand_platform_data {
 	/* indicate how many chip selects will be used */
 	int	num_cs;
 
+	/* use an flash-based bad block table */
+	bool	flash_bbt;
+
 	const struct mtd_partition		*parts[NUM_CHIP_SELECT];
 	unsigned int				nr_parts[NUM_CHIP_SELECT];
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:41 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:41 -0300
Subject: [PATCH v2 14/27] mtd: nand: pxa3xx: Add driver-specific ECC BCH
 support
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-15-git-send-email-ezequiel.garcia@free-electrons.com>

This commit adds the BCH ECC support available in NFCv2 controller.
Depending on the detected required strength the respective ECC layout
is selected.

This commit adds an empty ECC layout, since support to access large
pages is first required. Once that support is added, a proper ECC
layout will be added as well.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 90 +++++++++++++++++++++++++++++++++---------
 1 file changed, 72 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 451ebb6..5774ce9 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -56,6 +56,7 @@
 #define NDPCR		(0x18) /* Page Count Register */
 #define NDBDR0		(0x1C) /* Bad Block Register 0 */
 #define NDBDR1		(0x20) /* Bad Block Register 1 */
+#define NDECCCTRL	(0x28) /* ECC control */
 #define NDDB		(0x40) /* Data Buffer */
 #define NDCB0		(0x48) /* Command Buffer0 */
 #define NDCB1		(0x4C) /* Command Buffer1 */
@@ -196,6 +197,7 @@ struct pxa3xx_nand_info {
 
 	int			cs;
 	int			use_ecc;	/* use HW ECC ? */
+	int			ecc_bch;	/* using BCH ECC? */
 	int			use_dma;	/* use DMA ? */
 	int			use_spare;	/* use spare ? */
 
@@ -209,6 +211,8 @@ struct pxa3xx_nand_info {
 	unsigned int		fifo_size;	/* max. data size in the FIFO */
 	unsigned int		data_size;	/* data to be read from FIFO */
 	unsigned int		oob_size;
+	unsigned int		spare_size;
+	unsigned int		ecc_size;
 	int 			retcode;
 
 	/* cached register value */
@@ -343,19 +347,12 @@ static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
 
 	info->data_size = info->fifo_size;
-	if (!oob_enable) {
+	if (!oob_enable)
 		info->oob_size = 0;
-		return;
-	}
-
-	switch (info->fifo_size) {
-	case 2048:
-		info->oob_size = (info->use_ecc) ? 40 : 64;
-		break;
-	case 512:
-		info->oob_size = (info->use_ecc) ? 8 : 16;
-		break;
-	}
+	else if (info->use_ecc)
+		info->oob_size = info->spare_size;
+	else
+		info->oob_size = info->spare_size + info->ecc_size;
 }
 
 /**
@@ -370,10 +367,15 @@ static void pxa3xx_nand_start(struct pxa3xx_nand_info *info)
 
 	ndcr = info->reg_ndcr;
 
-	if (info->use_ecc)
+	if (info->use_ecc) {
 		ndcr |= NDCR_ECC_EN;
-	else
+		if (info->ecc_bch)
+			nand_writel(info, NDECCCTRL, 0x1);
+	} else {
 		ndcr &= ~NDCR_ECC_EN;
+		if (info->ecc_bch)
+			nand_writel(info, NDECCCTRL, 0x0);
+	}
 
 	if (info->use_dma)
 		ndcr |= NDCR_DMA_EN;
@@ -1074,6 +1076,43 @@ static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
 	return -ENODEV;
 }
 
+static int pxa_ecc_init(struct pxa3xx_nand_info *info,
+			struct nand_ecc_ctrl *ecc,
+			int strength, int page_size)
+{
+	/*
+	 * We don't use strength here as the PXA variant
+	 * is used with non-ONFI compliant devices.
+	 */
+	if (page_size == 2048) {
+		ecc->mode = NAND_ECC_HW;
+		ecc->size = 512;
+		ecc->strength = 1;
+
+		info->spare_size = 40;
+		info->ecc_size = 24;
+		return 1;
+
+	} else if (page_size == 512) {
+		ecc->mode = NAND_ECC_HW;
+		ecc->size = 512;
+		ecc->strength = 1;
+
+		info->spare_size = 8;
+		info->ecc_size = 8;
+		return 1;
+	}
+	return 0;
+}
+
+static int armada370_ecc_init(struct pxa3xx_nand_info *info,
+			      struct nand_ecc_ctrl *ecc,
+			      int strength, int page_size)
+{
+	/* Unimplemented yet */
+	return 0;
+}
+
 static int pxa3xx_nand_scan(struct mtd_info *mtd)
 {
 	struct pxa3xx_nand_host *host = mtd->priv;
@@ -1144,13 +1183,13 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
 	pxa3xx_flash_ids[1].name = NULL;
 	def = pxa3xx_flash_ids;
 KEEP_CONFIG:
-	chip->ecc.mode = NAND_ECC_HW;
-	chip->ecc.size = host->page_size;
-	chip->ecc.strength = 1;
-
 	if (info->reg_ndcr & NDCR_DWIDTH_M)
 		chip->options |= NAND_BUSWIDTH_16;
 
+	/* Device detection must be done with ECC disabled */
+	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+		nand_writel(info, NDECCCTRL, 0x0);
+
 	if (nand_scan_ident(mtd, 1, def))
 		return -ENODEV;
 
@@ -1161,6 +1200,21 @@ KEEP_CONFIG:
 		chip->bbt_md = &bbt_mirror_descr;
 	}
 
+	if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+		ret = armada370_ecc_init(info, &chip->ecc,
+				   chip->ecc_strength_ds,
+				   mtd->writesize);
+	else
+		ret = pxa_ecc_init(info, &chip->ecc,
+				   chip->ecc_strength_ds,
+				   mtd->writesize);
+	if (!ret) {
+		dev_err(&info->pdev->dev,
+			"ECC strength %d at page size %d is not supported\n",
+			chip->ecc_strength_ds, mtd->writesize);
+		return -ENODEV;
+	}
+
 	/* calculate addressing information */
 	if (mtd->writesize >= 2048)
 		host->col_addr_cycles = 2;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:46 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:46 -0300
Subject: [PATCH v2 19/27] mtd: nand: pxa3xx: Move the data buffer clean to
 prepare_start_command()
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-20-git-send-email-ezequiel.garcia@free-electrons.com>

To allow future support of multiple page reading/writing, move the data
buffer clean out of prepare_set_command().

This is done to prevent the data buffer from being cleaned on every command
preparation, when a multiple command sequence is implemented to read/write
pages larger than the FIFO size (2 KiB).

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 2858d10..e6222f1 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -614,6 +614,9 @@ static void set_command_address(struct pxa3xx_nand_info *info,
 
 static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 {
+	struct pxa3xx_nand_host *host = info->host[info->cs];
+	struct mtd_info *mtd = host->mtd;
+
 	/* reset data and oob column point to handle data */
 	info->buf_start		= 0;
 	info->buf_count		= 0;
@@ -638,6 +641,19 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 		info->ndcb2 = 0;
 		break;
 	}
+
+	/*
+	 * If we are about to isse a read command, or about to set
+	 * the write address, then clean the data buffer.
+	 */
+	if (command == NAND_CMD_READ0 ||
+	    command == NAND_CMD_READOOB ||
+	    command == NAND_CMD_SEQIN) {
+
+		info->buf_count = mtd->writesize + mtd->oobsize;
+		memset(info->data_buff, 0xFF, info->buf_count);
+	}
+
 }
 
 static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
@@ -679,16 +695,11 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
 
 		set_command_address(info, mtd->writesize, column, page_addr);
-		info->buf_count = mtd->writesize + mtd->oobsize;
-		memset(info->data_buff, 0xFF, info->buf_count);
 		break;
 
 	case NAND_CMD_SEQIN:
 
 		set_command_address(info, mtd->writesize, column, page_addr);
-		info->buf_count = mtd->writesize + mtd->oobsize;
-		memset(info->data_buff, 0xFF, info->buf_count);
-
 		break;
 
 	case NAND_CMD_PAGEPROG:
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:42 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:42 -0300
Subject: [PATCH v2 15/27] mtd: nand: pxa3xx: Clear cmd buffer #3 (NDCB3) on
 command start
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-16-git-send-email-ezequiel.garcia@free-electrons.com>

Command buffer #3 is not properly cleared and it keeps the last
set value. Fix this by clearing when a command is setup.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 5774ce9..be90304 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -611,6 +611,7 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 	info->use_ecc		= 0;
 	info->use_spare		= 1;
 	info->retcode		= ERR_NONE;
+	info->ndcb3		= 0;
 	if (info->cs != 0)
 		info->ndcb0 = NDCB0_CSEL;
 	else
@@ -632,7 +633,6 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 	default:
 		info->ndcb1 = 0;
 		info->ndcb2 = 0;
-		info->ndcb3 = 0;
 		break;
 	}
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:47 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:47 -0300
Subject: [PATCH v2 20/27] mtd: nand: pxa3xx: Fix SEQIN column address set
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-21-git-send-email-ezequiel.garcia@free-electrons.com>

This commit adds support page programming with a non-zero "column"
address setting. This is important to support OOB writing, through
command sequences such as:

  cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, ofs);
  write_buf(mtd, oob_buf, 6);
  cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index e6222f1..f6070f6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -699,7 +699,8 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 
 	case NAND_CMD_SEQIN:
 
-		set_command_address(info, mtd->writesize, column, page_addr);
+		info->buf_start = column;
+		set_command_address(info, mtd->writesize, 0, page_addr);
 		break;
 
 	case NAND_CMD_PAGEPROG:
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:45 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:45 -0300
Subject: [PATCH v2 18/27] mtd: nand: pxa3xx: Split prepare_command_pool() in
 two stages
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-19-git-send-email-ezequiel.garcia@free-electrons.com>

This commit splits the prepare_command_pool() function into two
stages: prepare_start_command() / prepare_set_command().

This is a preparation patch without any functionality changes,
and is meant to allow support fir multiple page reading/writing
operations.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 44 ++++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index cc5bcd1..2858d10 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -612,18 +612,8 @@ static void set_command_address(struct pxa3xx_nand_info *info,
 	}
 }
 
-static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
-		uint16_t column, int page_addr)
+static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 {
-	int addr_cycle, exec_cmd;
-	struct pxa3xx_nand_host *host;
-	struct mtd_info *mtd;
-
-	host = info->host[info->cs];
-	mtd = host->mtd;
-	addr_cycle = 0;
-	exec_cmd = 1;
-
 	/* reset data and oob column point to handle data */
 	info->buf_start		= 0;
 	info->buf_count		= 0;
@@ -632,10 +622,6 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 	info->use_spare		= 1;
 	info->retcode		= ERR_NONE;
 	info->ndcb3		= 0;
-	if (info->cs != 0)
-		info->ndcb0 = NDCB0_CSEL;
-	else
-		info->ndcb0 = 0;
 
 	switch (command) {
 	case NAND_CMD_READ0:
@@ -647,14 +633,32 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command,
 	case NAND_CMD_PARAM:
 		info->use_spare = 0;
 		break;
-	case NAND_CMD_SEQIN:
-		exec_cmd = 0;
-		break;
 	default:
 		info->ndcb1 = 0;
 		info->ndcb2 = 0;
 		break;
 	}
+}
+
+static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
+		uint16_t column, int page_addr)
+{
+	int addr_cycle, exec_cmd;
+	struct pxa3xx_nand_host *host;
+	struct mtd_info *mtd;
+
+	host = info->host[info->cs];
+	mtd = host->mtd;
+	addr_cycle = 0;
+	exec_cmd = 1;
+
+	if (info->cs != 0)
+		info->ndcb0 = NDCB0_CSEL;
+	else
+		info->ndcb0 = 0;
+
+	if (command == NAND_CMD_SEQIN)
+		exec_cmd = 0;
 
 	addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles
 				    + host->col_addr_cycles);
@@ -792,8 +796,10 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
 		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
 	}
 
+	prepare_start_command(info, command);
+
 	info->state = STATE_PREPARED;
-	exec_cmd = prepare_command_pool(info, command, column, page_addr);
+	exec_cmd = prepare_set_command(info, command, column, page_addr);
 	if (exec_cmd) {
 		init_completion(&info->cmd_complete);
 		init_completion(&info->dev_ready);
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:48 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:48 -0300
Subject: [PATCH v2 21/27] mtd: nand: pxa3xx: Add a read/write buffers markers
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-22-git-send-email-ezequiel.garcia@free-electrons.com>

In preparation to support multiple (aka chunked, aka splitted)
page I/O, this commit adds 'data_buff_pos' and 'oob_buff_pos' fields
to keep track of where the next read (or write) should be done.

This will allow multiple calls to handle_data_pio() to continue
the read (or write) operation.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 40 +++++++++++++++++++++++++++++-----------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index f6070f6..84ae555 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -174,6 +174,8 @@ struct pxa3xx_nand_info {
 	unsigned int 		buf_start;
 	unsigned int		buf_count;
 	unsigned int		buf_size;
+	unsigned int		data_buff_pos;
+	unsigned int		oob_buff_pos;
 
 	/* DMA information */
 	int			drcmr_dat;
@@ -342,11 +344,12 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host,
  * spare and ECC configuration.
  * Only applicable to READ0, READOOB and PAGEPROG commands.
  */
-static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info)
+static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info,
+				struct mtd_info *mtd)
 {
 	int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
 
-	info->data_size = info->fifo_size;
+	info->data_size = mtd->writesize;
 	if (!oob_enable)
 		info->oob_size = 0;
 	else if (info->use_ecc)
@@ -434,26 +437,39 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
 
 static void handle_data_pio(struct pxa3xx_nand_info *info)
 {
+	unsigned int do_bytes = min(info->data_size, info->fifo_size);
+
 	switch (info->state) {
 	case STATE_PIO_WRITING:
-		__raw_writesl(info->mmio_base + NDDB, info->data_buff,
-				DIV_ROUND_UP(info->data_size, 4));
+		__raw_writesl(info->mmio_base + NDDB,
+			      info->data_buff + info->data_buff_pos,
+			      DIV_ROUND_UP(do_bytes, 4));
+
 		if (info->oob_size > 0)
-			__raw_writesl(info->mmio_base + NDDB, info->oob_buff,
-					DIV_ROUND_UP(info->oob_size, 4));
+			__raw_writesl(info->mmio_base + NDDB,
+				      info->oob_buff + info->oob_buff_pos,
+				      DIV_ROUND_UP(info->oob_size, 4));
 		break;
 	case STATE_PIO_READING:
-		__raw_readsl(info->mmio_base + NDDB, info->data_buff,
-				DIV_ROUND_UP(info->data_size, 4));
+		__raw_readsl(info->mmio_base + NDDB,
+			     info->data_buff + info->data_buff_pos,
+			     DIV_ROUND_UP(do_bytes, 4));
+
 		if (info->oob_size > 0)
-			__raw_readsl(info->mmio_base + NDDB, info->oob_buff,
-					DIV_ROUND_UP(info->oob_size, 4));
+			__raw_readsl(info->mmio_base + NDDB,
+				     info->oob_buff + info->oob_buff_pos,
+				     DIV_ROUND_UP(info->oob_size, 4));
 		break;
 	default:
 		dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
 				info->state);
 		BUG();
 	}
+
+	/* Update buffer pointers for multi-page read/write */
+	info->data_buff_pos += do_bytes;
+	info->oob_buff_pos += info->oob_size;
+	info->data_size -= do_bytes;
 }
 
 #ifdef ARCH_HAS_DMA
@@ -621,6 +637,8 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 	info->buf_start		= 0;
 	info->buf_count		= 0;
 	info->oob_size		= 0;
+	info->data_buff_pos	= 0;
+	info->oob_buff_pos	= 0;
 	info->use_ecc		= 0;
 	info->use_spare		= 1;
 	info->retcode		= ERR_NONE;
@@ -631,7 +649,7 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 	case NAND_CMD_PAGEPROG:
 		info->use_ecc = 1;
 	case NAND_CMD_READOOB:
-		pxa3xx_set_datasize(info);
+		pxa3xx_set_datasize(info, mtd);
 		break;
 	case NAND_CMD_PARAM:
 		info->use_spare = 0;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:50 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:50 -0300
Subject: [PATCH v2 23/27] mtd: nand: pxa3xx: Add multiple chunk write support
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-24-git-send-email-ezequiel.garcia@free-electrons.com>

This commit adds write support for large pages (4 KiB, 8 KiB).
Such support is implemented by issuing a multiple command sequence,
transfering a set of 2 KiB chunks per transaction.

The splitted command sequence requires to send the SEQIN command
independently of the PAGEPROG command and therefore it's set as
an execution command.

Since PAGEPROG enables ECC, each 2 KiB chunk of data is written
together with ECC code at a controller-fixed location within
the flash page.

Currently, only devices with a 4 KiB page size has been tested.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 83 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 75 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index b297b22..5e92ef8 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -780,6 +780,20 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 
 		info->buf_start = column;
 		set_command_address(info, mtd->writesize, 0, page_addr);
+
+		/*
+		 * Multiple page programming needs to execute the initial
+		 * SEQIN command that sets the page address.
+		 */
+		if (mtd->writesize > PAGE_CHUNK_SIZE) {
+			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+				| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
+				| addr_cycle
+				| command;
+			/* No data transfer in this case */
+			info->data_size = 0;
+			exec_cmd = 1;
+		}
 		break;
 
 	case NAND_CMD_PAGEPROG:
@@ -789,13 +803,40 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 			break;
 		}
 
-		info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
-				| NDCB0_AUTO_RS
-				| NDCB0_ST_ROW_EN
-				| NDCB0_DBC
-				| (NAND_CMD_PAGEPROG << 8)
-				| NAND_CMD_SEQIN
-				| addr_cycle;
+		/* Second command setting for large pages */
+		if (mtd->writesize > PAGE_CHUNK_SIZE) {
+			/*
+			 * Multiple page write uses the 'extended command'
+			 * field. This can be used to issue a command dispatch
+			 * or a naked-write depending on the current stage.
+			 */
+			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+					| NDCB0_LEN_OVRD
+					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
+			info->ndcb3 = info->chunk_size +
+				      info->oob_size;
+
+			/*
+			 * This is the command dispatch that completes a chunked
+			 * page program operation.
+			 */
+			if (info->data_size == 0) {
+				info->ndcb0 = NDCB0_CMD_TYPE(0x1)
+					| NDCB0_EXT_CMD_TYPE(ext_cmd_type)
+					| command;
+				info->ndcb1 = 0;
+				info->ndcb2 = 0;
+				info->ndcb3 = 0;
+			}
+		} else {
+			info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
+					| NDCB0_AUTO_RS
+					| NDCB0_ST_ROW_EN
+					| NDCB0_DBC
+					| (NAND_CMD_PAGEPROG << 8)
+					| NAND_CMD_SEQIN
+					| addr_cycle;
+		}
 		break;
 
 	case NAND_CMD_PARAM:
@@ -942,6 +983,15 @@ static void armada370_nand_cmdfunc(struct mtd_info *mtd,
 	case NAND_CMD_READOOB:
 		ext_cmd_type = EXT_CMD_TYPE_MONO;
 		break;
+	case NAND_CMD_SEQIN:
+		ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
+		break;
+	case NAND_CMD_PAGEPROG:
+		ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
+		break;
+	default:
+		ext_cmd_type = -1;
+		break;
 	}
 
 	prepare_start_command(info, command);
@@ -979,7 +1029,16 @@ static void armada370_nand_cmdfunc(struct mtd_info *mtd,
 		}
 
 		/* Check if the sequence is complete */
-		if (info->data_size == 0)
+		if (info->data_size == 0 && command != NAND_CMD_PAGEPROG)
+			break;
+
+		/*
+		 * After a splitted program command sequence has issued
+		 * the command dispatch, the command sequence is complete.
+		 */
+		if (info->data_size == 0 &&
+		    command == NAND_CMD_PAGEPROG &&
+		    ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
 			break;
 
 		if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
@@ -988,6 +1047,14 @@ static void armada370_nand_cmdfunc(struct mtd_info *mtd,
 				ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
 			else
 				ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
+
+		/*
+		 * If a splitted program command has no more data to transfer,
+		 * the command dispatch must be issued to complete.
+		 */
+		} else if (command == NAND_CMD_PAGEPROG &&
+			   info->data_size == 0) {
+				ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
 		}
 	} while (1);
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:49 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:49 -0300
Subject: [PATCH v2 22/27] mtd: nand: pxa3xx: Introduce multiple page I/O
 support
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-23-git-send-email-ezequiel.garcia@free-electrons.com>

As preparation work to fully support large pages, this commit adds
the initial infrastructure to support splitted (aka chunked) I/O
operation. This commit adds support for read, and follow-up patches
will add write support.

When a read (aka READ0) command is issued, the driver loops issuing
the same command until all the requested data is transfered, changing
the 'extended' command field as needed.

For instance, if the driver is required to read a 4 KiB page, using a
chunk size of 2 KiB, the transaction is splitted in:
1. Monolithic read, first 2 KiB page chunk is read
2. Last naked read, second and last 2KiB page chunk is read

If ECC is enabled it is calculated on each chunk transfered and added
at a controller-fixed location after the data chunk that must be
spare area.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 192 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 185 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 84ae555..b297b22 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -7,6 +7,20 @@
  * 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.
+ *
+ * Large pages implementation
+ * --------------------------
+ *
+ * NAND stack expects data in the following format:
+ * ---------------------------
+ * | Data (4K) | Spare | ECC |
+ * ---------------------------
+ *
+ * While NAND controller expects data to be in the following format:
+ * -----------------------------------------------------
+ * | Data (2K) | Spare | ECC | Data (2K) | Spare | ECC |
+ * -----------------------------------------------------
+ *
  */
 
 #include <linux/kernel.h>
@@ -101,6 +115,8 @@
 #define NDCB0_ST_ROW_EN         (0x1 << 26)
 #define NDCB0_AUTO_RS		(0x1 << 25)
 #define NDCB0_CSEL		(0x1 << 24)
+#define NDCB0_EXT_CMD_TYPE_MASK	(0x7 << 29)
+#define NDCB0_EXT_CMD_TYPE(x)	(((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK)
 #define NDCB0_CMD_TYPE_MASK	(0x7 << 21)
 #define NDCB0_CMD_TYPE(x)	(((x) << 21) & NDCB0_CMD_TYPE_MASK)
 #define NDCB0_NC		(0x1 << 20)
@@ -111,6 +127,14 @@
 #define NDCB0_CMD1_MASK		(0xff)
 #define NDCB0_ADDR_CYC_SHIFT	(16)
 
+#define EXT_CMD_TYPE_DISPATCH	6 /* Command dispatch */
+#define EXT_CMD_TYPE_NAKED_RW	5 /* Naked read or Naked write */
+#define EXT_CMD_TYPE_READ	4 /* Read */
+#define EXT_CMD_TYPE_DISP_WR	4 /* Command dispatch with write */
+#define EXT_CMD_TYPE_FINAL	3 /* Final command */
+#define EXT_CMD_TYPE_LAST_RW	1 /* Last naked read/write */
+#define EXT_CMD_TYPE_MONO	0 /* Monolithic read/write */
+
 /* macros for registers read/write */
 #define nand_writel(info, off, val)	\
 	__raw_writel((val), (info)->mmio_base + (off))
@@ -212,6 +236,7 @@ struct pxa3xx_nand_info {
 
 	unsigned int		fifo_size;	/* max. data size in the FIFO */
 	unsigned int		data_size;	/* data to be read from FIFO */
+	unsigned int		chunk_size;	/* split commands chunk size */
 	unsigned int		oob_size;
 	unsigned int		spare_size;
 	unsigned int		ecc_size;
@@ -275,6 +300,31 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 	.pattern = bbt_mirror_pattern
 };
 
+static struct nand_ecclayout ecc_layout_4KB_bch4bit = {
+	.eccbytes = 64,
+	.eccpos = {
+		32,  33,  34,  35,  36,  37,  38,  39,
+		40,  41,  42,  43,  44,  45,  46,  47,
+		48,  49,  50,  51,  52,  53,  54,  55,
+		56,  57,  58,  59,  60,  61,  62,  63,
+		96,  97,  98,  99,  100, 101, 102, 103,
+		104, 105, 106, 107, 108, 109, 110, 111,
+		112, 113, 114, 115, 116, 117, 118, 119,
+		120, 121, 122, 123, 124, 125, 126, 127},
+	/* Bootrom looks in bytes 0 & 5 for bad blocks */
+	.oobfree = { {6, 26}, { 64, 32} }
+};
+
+static struct nand_ecclayout ecc_layout_4KB_bch8bit = {
+	.eccbytes = 128,
+	.eccpos = {
+		32,  33,  34,  35,  36,  37,  38,  39,
+		40,  41,  42,  43,  44,  45,  46,  47,
+		48,  49,  50,  51,  52,  53,  54,  55,
+		56,  57,  58,  59,  60,  61,  62,  63},
+	.oobfree = { }
+};
+
 /* Define a default flash type setting serve as flash detecting only */
 #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0])
 
@@ -437,7 +487,7 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask)
 
 static void handle_data_pio(struct pxa3xx_nand_info *info)
 {
-	unsigned int do_bytes = min(info->data_size, info->fifo_size);
+	unsigned int do_bytes = min(info->data_size, info->chunk_size);
 
 	switch (info->state) {
 	case STATE_PIO_WRITING:
@@ -675,7 +725,7 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 }
 
 static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
-		uint16_t column, int page_addr)
+		int ext_cmd_type, uint16_t column, int page_addr)
 {
 	int addr_cycle, exec_cmd;
 	struct pxa3xx_nand_host *host;
@@ -708,9 +758,20 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
 		if (command == NAND_CMD_READOOB)
 			info->buf_start += mtd->writesize;
 
-		/* Second command setting for large pages */
-		if (mtd->writesize >= PAGE_CHUNK_SIZE)
+		/*
+		 * Multiple page read needs an 'extended command type' field,
+		 * which is either naked-read or last-read according to the
+		 * state.
+		 */
+		if (mtd->writesize == PAGE_CHUNK_SIZE) {
 			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8);
+		} else if (mtd->writesize > PAGE_CHUNK_SIZE) {
+			info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
+					| NDCB0_LEN_OVRD
+					| NDCB0_EXT_CMD_TYPE(ext_cmd_type);
+			info->ndcb3 = info->chunk_size +
+				      info->oob_size;
+		}
 
 		set_command_address(info, mtd->writesize, column, page_addr);
 		break;
@@ -829,7 +890,8 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
 	prepare_start_command(info, command);
 
 	info->state = STATE_PREPARED;
-	exec_cmd = prepare_set_command(info, command, column, page_addr);
+	exec_cmd = prepare_set_command(info, command, -1, column, page_addr);
+
 	if (exec_cmd) {
 		init_completion(&info->cmd_complete);
 		init_completion(&info->dev_ready);
@@ -847,6 +909,91 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
 	info->state = STATE_IDLE;
 }
 
+static void armada370_nand_cmdfunc(struct mtd_info *mtd,
+				   const unsigned command,
+				   int column, int page_addr)
+{
+	struct pxa3xx_nand_host *host = mtd->priv;
+	struct pxa3xx_nand_info *info = host->info_data;
+	int ret, exec_cmd, ext_cmd_type;
+
+	/*
+	 * if this is a x16 device ,then convert the input
+	 * "byte" address into a "word" address appropriate
+	 * for indexing a word-oriented device
+	 */
+	if (info->reg_ndcr & NDCR_DWIDTH_M)
+		column /= 2;
+
+	/*
+	 * There may be different NAND chip hooked to
+	 * different chip select, so check whether
+	 * chip select has been changed, if yes, reset the timing
+	 */
+	if (info->cs != host->cs) {
+		info->cs = host->cs;
+		nand_writel(info, NDTR0CS0, info->ndtr0cs0);
+		nand_writel(info, NDTR1CS0, info->ndtr1cs0);
+	}
+
+	/* Select the extended command for the first command */
+	switch (command) {
+	case NAND_CMD_READ0:
+	case NAND_CMD_READOOB:
+		ext_cmd_type = EXT_CMD_TYPE_MONO;
+		break;
+	}
+
+	prepare_start_command(info, command);
+
+	/*
+	 * Prepare the "is ready" completion before starting a command
+	 * transaction sequence. If the command is not executed the
+	 * completion will be completed, see below.
+	 *
+	 * We can do that inside the loop because the command variable
+	 * is invariant and thus so is the exec_cmd.
+	 */
+	atomic_set(&info->is_ready, 0);
+	init_completion(&info->dev_ready);
+	do {
+		info->state = STATE_PREPARED;
+		exec_cmd = prepare_set_command(info, command, ext_cmd_type,
+					       column, page_addr);
+		if (!exec_cmd) {
+			atomic_set(&info->is_ready, 1);
+			complete(&info->dev_ready);
+			break;
+		}
+
+		init_completion(&info->cmd_complete);
+		pxa3xx_nand_start(info);
+
+		ret = wait_for_completion_timeout(&info->cmd_complete,
+				CHIP_DELAY_TIMEOUT);
+		if (!ret) {
+			dev_err(&info->pdev->dev, "Wait time out!!!\n");
+			/* Stop State Machine for next command cycle */
+			pxa3xx_nand_stop(info);
+			break;
+		}
+
+		/* Check if the sequence is complete */
+		if (info->data_size == 0)
+			break;
+
+		if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
+			/* Last read: issue a 'last naked read' */
+			if (info->data_size == info->chunk_size)
+				ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
+			else
+				ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
+		}
+	} while (1);
+
+	info->state = STATE_IDLE;
+}
+
 static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
 		struct nand_chip *chip, const uint8_t *buf, int oob_required)
 {
@@ -1032,6 +1179,8 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
 		host->read_id_bytes = 2;
 	}
 
+	/* Set an initial chunk size */
+	info->chunk_size = info->fifo_size;
 	info->reg_ndcr = ndcr & ~NDCR_INT_MASK;
 	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
 	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
@@ -1136,6 +1285,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
 		ecc->size = 512;
 		ecc->strength = 1;
 
+		info->chunk_size = 2048;
 		info->spare_size = 40;
 		info->ecc_size = 24;
 		return 1;
@@ -1145,6 +1295,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
 		ecc->size = 512;
 		ecc->strength = 1;
 
+		info->chunk_size = 512;
 		info->spare_size = 8;
 		info->ecc_size = 8;
 		return 1;
@@ -1156,7 +1307,30 @@ static int armada370_ecc_init(struct pxa3xx_nand_info *info,
 			      struct nand_ecc_ctrl *ecc,
 			      int strength, int page_size)
 {
-	/* Unimplemented yet */
+	if (strength == 4 && page_size == 4096) {
+		ecc->mode = NAND_ECC_HW;
+		ecc->size = 512;
+		ecc->layout = &ecc_layout_4KB_bch4bit;
+		ecc->strength = 4;
+
+		info->ecc_bch = 1;
+		info->chunk_size = 2048;
+		info->spare_size = 32;
+		info->ecc_size = 32;
+		return 1;
+
+	} else if (strength == 8 && page_size == 4096) {
+		ecc->mode = NAND_ECC_HW;
+		ecc->size = 512;
+		ecc->layout = &ecc_layout_4KB_bch8bit;
+		ecc->strength = 8;
+
+		info->ecc_bch = 1;
+		info->chunk_size = 1024;
+		info->spare_size = 0;
+		info->ecc_size = 32;
+		return 1;
+	}
 	return 0;
 }
 
@@ -1320,12 +1494,16 @@ static int alloc_nand_resource(struct platform_device *pdev)
 		chip->controller        = &info->controller;
 		chip->waitfunc		= pxa3xx_nand_waitfunc;
 		chip->select_chip	= pxa3xx_nand_select_chip;
-		chip->cmdfunc		= pxa3xx_nand_cmdfunc;
 		chip->read_word		= pxa3xx_nand_read_word;
 		chip->read_byte		= pxa3xx_nand_read_byte;
 		chip->read_buf		= pxa3xx_nand_read_buf;
 		chip->write_buf		= pxa3xx_nand_write_buf;
 		chip->options		|= NAND_NO_SUBPAGE_WRITE;
+
+		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
+			chip->cmdfunc = armada370_nand_cmdfunc;
+		else
+			chip->cmdfunc = pxa3xx_nand_cmdfunc;
 	}
 
 	spin_lock_init(&chip->controller->lock);
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:51 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:51 -0300
Subject: [PATCH v2 24/27] mtd: nand: pxa3xx: Add ECC BCH correctable errors
 detection
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-25-git-send-email-ezequiel.garcia@free-electrons.com>

This commit extends the ECC correctable error detection to include
ECC BCH errors. The number of BCH correctable errors can be any up to 16,
and the actual value is exposed in the NDSR register.

Therefore, we change some symbol names to refer to correctable or
uncorrectable (instead of single-bit or double-bit as it was in the
Hamming case) and while at it, cleanup the detection code slightly.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/pxa3xx_nand.c | 43 +++++++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 5e92ef8..cbc7240 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -97,6 +97,9 @@
 #define NDCR_INT_MASK           (0xFFF)
 
 #define NDSR_MASK		(0xfff)
+#define NDSR_ERR_CNT_OFF	(16)
+#define NDSR_ERR_CNT_MASK       (0x1f)
+#define NDSR_ERR_CNT(sr)	((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK)
 #define NDSR_RDY                (0x1 << 12)
 #define NDSR_FLASH_RDY          (0x1 << 11)
 #define NDSR_CS0_PAGED		(0x1 << 10)
@@ -105,8 +108,8 @@
 #define NDSR_CS1_CMDD		(0x1 << 7)
 #define NDSR_CS0_BBD		(0x1 << 6)
 #define NDSR_CS1_BBD		(0x1 << 5)
-#define NDSR_DBERR		(0x1 << 4)
-#define NDSR_SBERR		(0x1 << 3)
+#define NDSR_UNCORERR		(0x1 << 4)
+#define NDSR_CORERR		(0x1 << 3)
 #define NDSR_WRDREQ		(0x1 << 2)
 #define NDSR_RDDREQ		(0x1 << 1)
 #define NDSR_WRCMDREQ		(0x1)
@@ -147,9 +150,9 @@ enum {
 	ERR_NONE	= 0,
 	ERR_DMABUSERR	= -1,
 	ERR_SENDCMD	= -2,
-	ERR_DBERR	= -3,
+	ERR_UNCORERR	= -3,
 	ERR_BBERR	= -4,
-	ERR_SBERR	= -5,
+	ERR_CORERR	= -5,
 };
 
 enum {
@@ -240,6 +243,7 @@ struct pxa3xx_nand_info {
 	unsigned int		oob_size;
 	unsigned int		spare_size;
 	unsigned int		ecc_size;
+	unsigned int		ecc_err_cnt;
 	int 			retcode;
 
 	/* cached register value */
@@ -590,10 +594,16 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid)
 
 	status = nand_readl(info, NDSR);
 
-	if (status & NDSR_DBERR)
-		info->retcode = ERR_DBERR;
-	if (status & NDSR_SBERR)
-		info->retcode = ERR_SBERR;
+	if (status & NDSR_UNCORERR)
+		info->retcode = ERR_UNCORERR;
+	if (status & NDSR_CORERR) {
+		info->retcode = ERR_CORERR;
+		if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 &&
+		    info->ecc_bch)
+			info->ecc_err_cnt = NDSR_ERR_CNT(status);
+		else
+			info->ecc_err_cnt = 1;
+	}
 	if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) {
 		/* whether use dma to transfer data */
 		if (info->use_dma) {
@@ -692,6 +702,7 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command)
 	info->use_ecc		= 0;
 	info->use_spare		= 1;
 	info->retcode		= ERR_NONE;
+	info->ecc_err_cnt	= 0;
 	info->ndcb3		= 0;
 
 	switch (command) {
@@ -1080,20 +1091,14 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
 	chip->read_buf(mtd, buf, mtd->writesize);
 	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 
-	if (info->retcode == ERR_SBERR) {
-		switch (info->use_ecc) {
-		case 1:
-			mtd->ecc_stats.corrected++;
-			break;
-		case 0:
-		default:
-			break;
-		}
-	} else if (info->retcode == ERR_DBERR) {
+	if (info->retcode == ERR_CORERR && info->use_ecc) {
+		mtd->ecc_stats.corrected += info->ecc_err_cnt;
+
+	} else if (info->retcode == ERR_UNCORERR) {
 		/*
 		 * for blank page (all 0xff), HW will calculate its ECC as
 		 * 0, which is different from the ECC information within
-		 * OOB, ignore such double bit errors
+		 * OOB, ignore such ucorrectable errors
 		 */
 		if (is_buf_blank(buf, mtd->writesize))
 			info->retcode = ERR_NONE;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:52 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:52 -0300
Subject: [PATCH v2 25/27] ARM: mvebu: Add support for NAND controller in
 Armada 370/XP
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-26-git-send-email-ezequiel.garcia@free-electrons.com>

The Armada 370 and Armada XP SoC have a NAND controller (aka NFCv2).
This commit adds support for it in Armada 370 and Armada XP SoC
common devicetree.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/boot/dts/armada-370-xp.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi
index 01e69fc..b4e6898 100644
--- a/arch/arm/boot/dts/armada-370-xp.dtsi
+++ b/arch/arm/boot/dts/armada-370-xp.dtsi
@@ -258,6 +258,15 @@
 				status = "disabled";
 			};
 
+			nand at d0000 {
+				compatible = "marvell,armada370-nand";
+				reg = <0xd0000 0x54>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				interrupts = <113>;
+				clocks = <&coredivclk 0>;
+				status = "disabled";
+			};
 		};
 	};
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:53 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:53 -0300
Subject: [PATCH v2 26/27] ARM: mvebu: Enable NAND controller in Armada XP GP
 board
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-27-git-send-email-ezequiel.garcia@free-electrons.com>

The Armada XP GP board has a NAND flash, so enable it in the devicetree.

In order to skip the driver's custom device detection and use only ONFI
detection, the "marvell,keep-config" parameter is used.
This is needed because we haven't support for setting the timings
parameters yet and must rely in bootloader's.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/boot/dts/armada-xp-gp.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/armada-xp-gp.dts b/arch/arm/boot/dts/armada-xp-gp.dts
index 2298e4a..274e2ad 100644
--- a/arch/arm/boot/dts/armada-xp-gp.dts
+++ b/arch/arm/boot/dts/armada-xp-gp.dts
@@ -175,6 +175,14 @@
 					spi-max-frequency = <108000000>;
 				};
 			};
+
+			nand at d0000 {
+				status = "okay";
+				num-cs = <1>;
+				marvell,nand-keep-config;
+				marvell,nand-enable-arbiter;
+				nand-on-flash-bbt;
+			};
 		};
 	};
 };
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 18 19:02:54 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 18 Oct 2013 20:02:54 -0300
Subject: [PATCH v2 27/27] ARM: mvebu: Enable NAND controller in Armada 370
 Mirabox
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382137374-21251-28-git-send-email-ezequiel.garcia@free-electrons.com>

The Armada 370 Mirabox has a NAND flash, so enable it in the devicetree
and add the partitions as prepared in the factory images.

In order to skip the driver's custom device detection and use only
ONFI detection, the "marvell,keep-config" parameter is used.
This is needed because we have no support for setting the timings parameters yet.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/boot/dts/armada-370-mirabox.dts | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts
index 2471d9d..1e73017 100644
--- a/arch/arm/boot/dts/armada-370-mirabox.dts
+++ b/arch/arm/boot/dts/armada-370-mirabox.dts
@@ -139,6 +139,27 @@
 					reg = <0x25>;
 				};
 			};
+
+			nand at d0000 {
+				status = "okay";
+				num-cs = <1>;
+				marvell,nand-keep-config;
+				marvell,nand-enable-arbiter;
+				nand-on-flash-bbt;
+
+				partition at 0 {
+					label = "U-Boot";
+					reg = <0 0x400000>;
+				};
+				partition at 400000 {
+					label = "Linux";
+					reg = <0x400000 0x400000>;
+				};
+				partition at 800000 {
+					label = "Filesystem";
+					reg = <0x800000 0x3f800000>;
+				};
+			};
 		};
 	};
 };
-- 
1.8.1.5



From computersforpeace at gmail.com  Fri Oct 18 21:37:06 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 18 Oct 2013 18:37:06 -0700
Subject: [PATCH v2] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <20131018193211.GA30464@localhost>
References: <1382120072-30057-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAN8TOE-hxcaj79hTxDMzP1On69n=3QdBy45fjePLrQuzSvnnyw@mail.gmail.com>
 <20131018193211.GA30464@localhost>
Message-ID: <CAN8TOE8L2jQ3nFxf5hxSw8qnFK3m4NuexbZ=yuwoS=uoFiVAnw@mail.gmail.com>

On Fri, Oct 18, 2013 at 12:32 PM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> On Fri, Oct 18, 2013 at 12:15:39PM -0700, Brian Norris wrote:
>> On Fri, Oct 18, 2013 at 11:14 AM, Ezequiel Garcia
>> <ezequiel.garcia at free-electrons.com> wrote:
[...]
>> >  drivers/mtd/nand/pxa3xx_nand.c | 6 ++++--
>> >  1 file changed, 4 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
>> > index aa75adf..4d53e8e 100644
>> > --- a/drivers/mtd/nand/pxa3xx_nand.c
>> > +++ b/drivers/mtd/nand/pxa3xx_nand.c
>> > @@ -46,6 +46,8 @@
>> >   */
>> >  #define INIT_BUFFER_SIZE       256
>> >
>> > +#define DRIVER_NAME            "pxa3xx_nand-0"
>> > +
>> >  /* registers and bit definitions */
>> >  #define NDCR           (0x00) /* Control register */
>> >  #define NDTR0CS0       (0x04) /* Timing Parameter 0 for CS0 */
>> > @@ -1339,7 +1341,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
>> >         for (cs = 0; cs < pdata->num_cs; cs++) {
>> >                 struct mtd_info *mtd = info->host[cs]->mtd;
>> >
>> > -               mtd->name = pdev->name;
>> > +               mtd->name = DRIVER_NAME;
>> >                 info->cs = cs;
>> >                 ret = pxa3xx_nand_scan(mtd);
>> >                 if (ret) {
>> > @@ -1425,7 +1427,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
>> >
>> >  static struct platform_driver pxa3xx_nand_driver = {
>> >         .driver = {
>> > -               .name   = "pxa3xx-nand",
>> > +               .name   = DRIVER_NAME,
>> >                 .of_match_table = pxa3xx_nand_dt_ids,
>> >         },
>> >         .probe          = pxa3xx_nand_probe,
>>
>> For mtdparts' sake, do we need both the driver name and the MTD name
>> to be the same? Or could we just stick the  "pxa3xx_nand-0" directly
>> in mtd->name only, where it's needed for compatibility, and allow the
>> driver name to be cleaner? Or is that a silly idea?
>>
>
> Hm... What's the impact of the driver's name?

I meant to ask you the exact same question, because I'm lazy :)

I'm not sure exactly. I thought it affected the device name (which is
important to users; it's exposed in sysfs in potentially important
ways), but that actually comes from the platform-device allocation or
from device tree. The most visible way I know of is that it prefixes
the messages seen via the dev_{printk,err,info,warn,..}() print
functions. This could be annoying, but not horrible.

The driver name does show up in /sys/bus/platform/drivers, but I'm not
sure if that's ever expected to be stable.

> I know it's just a small bloat, but still I don't like to see two stupid
> strings "pxa3xx-nand" and "pxa3xx_nand-0" bloating our kernels, so
> that's why I chose a common macro :-)

That's fine.

> What do you think?

I'm fine with just making both use DRIVER_NAME. So I'd take this patch as-is.

One possible consequence: it makes things a little more fragile if
people want to change one or both in the future, not noticing that
while the driver name may (?) be changed harmlessly, it can cause
mtdparts=... breakage.

Brian


From computersforpeace at gmail.com  Fri Oct 18 22:01:26 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 18 Oct 2013 19:01:26 -0700
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <5260DA32.4090502@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>
 <5260DA32.4090502@freescale.com>
Message-ID: <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>

On Thu, Oct 17, 2013 at 11:50 PM, Huang Shijie <b32955 at freescale.com> wrote:
> ? 2013?08?27? 17:29, Huang Shijie ??:
>> Current gpmi-nand driver only supports one chips. But we may meet
>> some embarrassing situation, such as Micron MT29F32G08QAA.
>> This nand chip has two DIEs internally. Each die has its own chip select pin,
>> so this chip acts as two nand chips.
>>
>> If we only scan one chip, we may find that we only get 2G for this chip,
>> but in actually, this chip's size is 4G.
>>
>> So scan two chips by default.
>>
>> In order to support two nand chips, we have to do the following:
>>    1.) Decouple the chip select from the DMA channel,
>>        We can use the dma 0 to access all the nand chips.
>>
>>    2.) fix the wrong method of checking the ready/busy status.
>>       In the imx6, all the ready/busy pins are binding together, we
>>       should check ready/busy status of chip 0 for the all the chips.
>>
>> Tested this patch set with MT29F32G08QAA.
>>
>> To Brian:
>>       My "better" solution was proved to be a bad idea. So i resend this
>>       patch set again.
>>
>> v1 --> v2:
>>       [0] rebase on the latest l2-mtd tree.
>>
>> Huang Shijie (4):
>>   mtd: gpmi: decouple the chip select from the DMA channel
>>   mtd: gpmi: use DMA channel 0 for all the nand chips
>>   mtd: gpmi: scan two nand chips
>>   mtd: gpmi: imx6: fix the wrong method for checking ready/busy
>>
>>  drivers/mtd/nand/gpmi-nand/gpmi-lib.c  |   13 +++++++++++++
>>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    7 +++----
>>  drivers/mtd/nand/gpmi-nand/gpmi-regs.h |    3 +++
>>  3 files changed, 19 insertions(+), 4 deletions(-)
>>
> Hi Artem & Brian:
> Could you please merge this patch set?
> it seems you have missed this patch set.

Yes, I seem to have overlooked this set. I think it must have come in
parallel with your MLC patch set, so I delayed it until the MLC patch
set settled down?

Anyway, I'll revisit this soon. But I probably need to take care of
your mtd-utils updates first, since they should go along with the MLC
patch set.

And on top of that (to update the world on daily status), I seem to be
tripping over some UBIFS bugs that are inhibiting the validation I'm
trying to do for some new hardware. So, I'm all-around pretty busy!
I'll get myself together next week, hopefully.

In the meantime, other people's code could use some extra eyes. I know
Ezequiel just sent out a 27 (!) patch series today. There's also the
pending cmdline.c patch from months ago, where Cai Zhiyong wanted to
migrate our command line partition parser to a common
block/cmdline-parser.c. Part of her work (for block devices) is
upstream already, and part has just sat on our mailing list without
eyes to test it...

See: http://lists.infradead.org/pipermail/linux-mtd/2013-August/048101.html

And finally, I believe Tim Harvey has just reported ECC regressions
for GPMI NAND on some of your code that made it into 3.12 so far. That
issue is probably more urgent than new features.

Brian


From pekon at ti.com  Sat Oct 19 01:10:51 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Sat, 19 Oct 2013 05:10:51 +0000
Subject: [PATCH v9 3/9] mtd: nand: omap: cleanup: replace local
 references with generic framework names
In-Reply-To: <20131016213024.GY23337@ld-irv-0074.broadcom.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-4-git-send-email-pekon@ti.com>
 <20131016213024.GY23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA28C91@DBDE04.ent.ti.com>

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On Tue, Oct 15, 2013 at 11:19:51AM +0530, Pekon Gupta wrote:
> > This patch updates following in omap_nand_probe() and
> omap_nand_remove()
> > - replaces "info->nand" with "nand_chip" (struct nand_chip *nand_chip)
> > - replaces "info->mtd" with "mtd" (struct mtd_info *mtd)
> > - white-space and formatting cleanup
> >
> > Signed-off-by: Pekon Gupta <pekon at ti.com>
> 
> This patch looks good. Thanks for being consistent.
> 

> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index 8d521aa..5596368 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> 
> ...
> 
> > @@ -1846,17 +1848,16 @@ static int omap_nand_probe(struct
> > -
> > -	info->nand.options	= pdata->devsize;
> > -	info->nand.options	|= NAND_SKIP_BBTSCAN;
> > +	mtd			= &info->mtd;
> > +	mtd->priv		= &info->nand;
> > +	mtd->name		= dev_name(&pdev->dev);
> > +	mtd->owner		= THIS_MODULE;
> > +	nand_chip		= &info->nand;
> > +	nand_chip->options	= pdata->devsize;
> 
> Trivial side comment: the 'devsize' field is not named very
> informatively. It is apparently just a way to specify nand_chip.options,
> and it is only actually used for setting a buswidth. (It is also badly
> named nand_type in other places.) Not sure if it's worth improving, or
> even dropping at some later point in time.
> 
For now I'm keeping this name consistent for now, as this would require
touching GPMC driver also, where 'devsize' is used to configure
GPMC controller registers.

I'll keep this feedback as pending for independent patch where I probe
driver with "NAND_BUSWIDTH_AUTO".


with regards, pekon


From w at 1wt.eu  Sat Oct 19 02:35:35 2013
From: w at 1wt.eu (Willy Tarreau)
Date: Sat, 19 Oct 2013 08:35:35 +0200
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131019063535.GC20157@1wt.eu>

Hi Ezequiel,

On Fri, Oct 18, 2013 at 08:02:27PM -0300, Ezequiel Garcia wrote:
> Hi guys,
> 
> This is the v2 of the work implementing NAND support in Armada 370/XP SoCs.
> This series is probably not yet complete (see below), but I feel like
> we're really closer now :-)
> 
> As in the previous version and given I don't have any public datasheet
> to show, I'll try to write some of the most relevant parts of the controller.
> 
> * NFCv2 controller background
> 
> The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
> larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
> chunked transfers.
> 
> For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
> we'll have this layout in the pages:
> 
>   ------------------------------------------------------------------------------
>   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
>   ------------------------------------------------------------------------------
> 
> The driver reads the data and spare portions independently and builds an internal
> buffer with this layout (in the 4 KiB page case):
> 
>   ------------------------------------------
>   |     4096B data     |     64B spare     |
>   ------------------------------------------
> 
> Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
> OOB, one per chunk read.
> 
>   -------------------------------------------------------------------
>   |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC |
>   -------------------------------------------------------------------
> 
> So, in order to achieve reading (for instance), we issue several READ0 commands
> (with some additional controller-specific magic) and read two chunks of 2080B
> (2048 data + 32 spare) each.
> The driver accomodates this data to expose the NAND core a contiguous buffer
> (4096 data + spare) or (4096 + spare + ECC + spare + ECC).
> 
> * ECC
> 
> The controller has built-in hardware ECC capabilities. In addition it is
> configurable between two modes: 1) Hamming, 2) BCH.
> 
> Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
> the controller is configured to transfer the data.
> 
> In the BCH mode the ECC code will be calculated for each transfered chunk
> and expected to be located (when reading/programming) right after the spare
> bytes as the figure above shows.
> 
> So, repeating the above scheme, a 2048B data chunk will be followed by 32B
> spare, and then the ECC controller will read/write the ECC code (30B in
> this case):
> 
>   ------------------------------------
>   | 2048B data | 32B spare | 30B ECC |
>   ------------------------------------
> 
> If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
> If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
> So in Hamming mode, a 2048B page will have a 24B ECC.
> 
> Despite all of the above, the controller requires the driver to only read or
> write in multiples of 8-bytes, because the data buffer is 64-bits.
> 
> * Changes from v1
> 
> Aside from several changes based in Brian's feedback, the main changes
> from v1 are:
> 
>   * The controller's clock source is now fully modeled, see patche 1 to 4.
>     Of course, none of those patches should be taken through the mtd
>     subsystem, but I'm adding them here for completeness.
> 
>   * The chip's cmdfunc() is now independently implemented in each SoC variant.
>     The rationale behind this decision is that 'chunked' I/O is the only tested
>     mode on the Armada370 variant, while the old 'vanilla' I/O is the only
>     tested mode on the PXA variant.
> 
>     So it's safer to have an implementation for each variant.
> 
>   * Added support for BCH-8, in other words: 8-bits of correction in a 512-byte
>     region. This is obtained by using a data chunk size of 1024B, thus doubling
>     the ECC BCH strength, as per this ECC engine mechanism.
> 
>   * The ECC layout in use, which must be set according to the page size and
>     desired ECC strength is now strictly chosen to match only the tested
>     combinations.
> 
> * Pending stuff
> 
>   1. Factory bad blocks handling
> 
>   Currently, there's no factory bad block initial scan (when the bad block
>   table is missing). The ECC BCH requires to layout the device's pages in
>   a splitted "data + OOB + data + OOB" way. This layout being different from
>   the factory layout. In other words,
> 
>   Factory view:
> 
>   -----------------------------------------------
>   |                    Data           |x  OOB   |
>   -----------------------------------------------
> 
>   Driver's view:
> 
>   -----------------------------------------------
>   |      Data      | OOB |      Data   x  | OOB |
>   -----------------------------------------------
> 
>   It can be seen from the above, that the factory bad block marker must be
>   searched within the 'data' region, and not in the usual OOB region.
> 
>   This seems to be similar to the gpmi-nand driver, yet I really find its
>   'bad block swapping' solution odd, so I'm trying to find something
>   cleaner.
> 
>   2. ECC modeling
> 
>   Although I've exposed some ECC information in the ECC layout, I'm still
>   not sure why is this needed, or if it's needed at all.
> 

I strongly believe that all the information above is very valuable and
that it's a shame to lose it in a cover message. It would definitely
make sense to have this in a doc file.

Best regards,
Willy



From ana.flavia at lidertel.com.br  Sat Oct 19 03:26:10 2013
From: ana.flavia at lidertel.com.br (Ana Flavia Maria)
Date: Sat, 19 Oct 2013 04:26:10 -0300 (BRT)
Subject: !
Message-ID: <1202370077.2226556.1382167570393.JavaMail.root@lidertel.com.br>



-- 
                                     Loan at 3% interest rate Loan offer.. AreYou Interested>?


From pekon at ti.com  Sat Oct 19 04:44:04 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:04 +0530
Subject: [PATCH v10 00/10] mtd:nand:omap2: clean-up of supported ECC schemes
Message-ID: <1382172254-12448-1-git-send-email-pekon@ti.com>


*changes v9 -> v10*
[PATCH 1/10], [PATCH 2/10]
  swapped [PATCH v9 1/9] and [PATCH v9 2/9] so that DT parsing updates
  (with backward compatibility) happen before the deprecation of DT values.
  This way DTB does not break functionally between the patches.
[PATCH 3/10] <no update>
[PATCH 4/10] 
  dropped [PATCH v9 4/9] introducing NAND_BUSWIDTH_AUTO, instead
  using DT 'nand-bus-width' for device bus-width
[PATCH 5/10] <no update>
[PATCH 6/10] <no update>
[PATCH 7/10] 
  separated out drivers/mtd/nand/Kconfig updates into separate [PATCH v10 10/10]
  cleanup: s/info->nand\./nand_chip->
[PATCH 8/10] <no update>
[PATCH 9/10] cleanup: s/out_release_mem_region/return_error
[PATCH 10/10] <new> spawned from [PATCH v9 8/9] for Kconfig updates


*changes v8 -> v9*
[PATCH 1/9] <no update from [PATCH v8 1/6]>
[PATCH 2/9] <only commit log updated from [PATCH v8 2/6]>
 As per feedbacks from Brian Norris <computersforpeace at gmail.com> previous
 revision [PATCH v8 3/6] and [PATCH 4/6] are split into following sub-patches:
- [PATCH 3/9] <new> replaces local reference with generic names (mtd, nand_chip)
- [PATCH 4/9] <new> enables auto-detection of bus-width
- [PATCH 5/9] <new> removes omap3_init_bch: populates ecc-scheme data
- [PATCH 6/9] <new> removes omap3_init_bch_tail: populates ecc-layout
- [PATCH 7/9] <new> replaces lib/bch.c with nand_bch.c wrapper
[PATCH 8/9] <no update same as [PATCH v8 5/6]
[PATCH 9/9] removed devm_free_xx functions


*Changes v7 -> v8*
[PATCH 1/6] <no updates>
[PATCH 2/6]
	- updated DT parsing of "ti,nand-ecc-opts" so that its "ham1" remains
		compatible to "sw","hw","hw-romcode"
	- updated DT parsing of "ti,elm-id" to retain compatibility to "elm_id"
	- using of_parse_phandle() to get ELM device pointer from DT
[PATCH 3..6/6] <commit log updates>


*Changes v6 -> v7*
[PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks from Brian Norris <computersforpeace at gmail.com>
[PATCH 2/6] incorporated feedbacks from DT maintainers
[PATCH 3/6] cleaned and incorporated feedbacks from Brian Norris <computersforpeace at gmail.com>
[PATCH 4/6] rebasing changes and cleanup
[PATCH 5/6] updated omap3430-sdp.dts
[PATCH 6/6] <NEW> updated for devm_xx


*Changes v5 -> v6*
[PATCH 1/4]: 
	- updated DT binding for gpmc-nand based on 'Olof Johansson's feedbacks
	http://lists.infradead.org/pipermail/linux-mtd/2013-August/048394.html
	- detection of ELM device via ti,elm-id DT node, moved to gpmc.c driver
[PATCH 2/4]
	- removed: support for following obselete ECC schemes
	OMAP_ECC_HAMMING_CODE_DEFAULT (S/W based 1-bit Hamming ECC)
	OMAP_ECC_HAMMING_CODE_HW_ROMCODE (H/W based 1-bit Hamming ECC scheme)
	- updated: using omap_oobinfo as chip->ecc.layout for all ecc-schemes
	- clean: error messages
[PATCH 3/4] cleaned to include changes for OMAP_ECC_BCH8_CODE_HW only
[PATCH 4/4] updated to include DT property changes


*Changes v4 -> v5*
- Rebased to linux-next 
IMPORTANT: Need to revert commit fb1585b, [PATCH 2/4] part of previous version
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047441.html

- Swapped PATCH-1 & PATCH-2 to maintain bisectibility & compilation dependency
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047461.html

- PATCH-2: re-ordered call to is_elm_present() for later updates ELM driver
	- dropped changes in include/linux/platform_data/elm.h (not needed)
- PATCH-3: re-ordered call to is_elm_present() for later updates ELM driver
- Re-formated patch description (replaced tabs with white-spaces)


*Changes v3 -> v4*
(Resent with CC: devicetree-discuss at lists.ozlabs.org)
- [Patch 1/3] removed MTD_NAND_OMAP_BCH8 & MTD_NAND_OMAP_BCH4 from nand/Kconfig
	ECC scheme selectable via nand DT (nand-ecc-opt).
- [*] rebased for l2-mtd.git


*Changes v2 -> v3*
(Resent with Author Name fixed)
- PATCH-1: re-arranged code to remove redundancy, added NAND_BUSWIDTH_AUTO
- PATCH-2: updated nand-ecc-opt DT mapping and Documentation
- PATCH-3: code-cleaning + changes to match PATCH-1
- PATCH-4 <DROPPED> update DT attribute for ti,nand-ecc-opt 
	- received feedback to keep DT mapping independent of linuxism
- PATCH-4:<NEW> : ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
	- independent patch for AM335x-evm.dts update based on PATCH-2


*Changes v1 -> v2*
	added 	[PATCH 3/4] and [PATCH 4/4]


After this patch series, omap2-nand driver will supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+


Pekon Gupta (10):
  ARM: OMAP2+: cleaned-up DT support of various ECC schemes
  mtd: nand: omap: combine different flavours of 1-bit hamming ecc
    schemes
  mtd: nand: omap: cleanup: replace local references with generic
    framework names
  mtd: nand: omap: fix device scan: NAND_CMD_READID, NAND_CMD_RESET,
    CMD_CMD_PARAM use only x8 bus
  mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
    device_probe
  mtd: nand: omap: clean-up ecc layout for BCH ecc schemes
  mtd: nand: omap: use drivers/mtd/nand/nand_bch.c wrapper for BCH ECC
    instead of lib/bch.c
  ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
  mtd: nand: omap: updated devm_xx for all resource allocation and free
    calls
  mtd: nand: omap: remove selection of BCH ecc-scheme via KConfig

 .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
 arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
 arch/arm/mach-omap2/board-flash.c                  |   2 +-
 arch/arm/mach-omap2/gpmc.c                         |  48 +-
 drivers/mtd/nand/Kconfig                           |  40 +-
 drivers/mtd/nand/omap2.c                           | 665 ++++++++++-----------
 include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
 8 files changed, 372 insertions(+), 422 deletions(-)

-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:06 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:06 +0530
Subject: [PATCH v10 02/10] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-3-git-send-email-pekon@ti.com>

OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
ecc-scheme, like:
- OMAP_ECC_HAMMING_CODE_DEFAULT
	1-bit hamming ecc code using software library
- OMAP_ECC_HAMMING_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine
- OMAP_ECC_HAMMING_CODE_HW_ROMCODE
	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
	to ROM code.

This patch combines above multiple ecc-schemes into single implementation:
- OMAP_ECC_HAM1_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
	ecc-layout.

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
 arch/arm/mach-omap2/board-flash.c                   | 2 +-
 drivers/mtd/nand/omap2.c                            | 9 +++------
 include/linux/platform_data/mtd-nand-omap2.h        | 7 +------
 4 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index bfe07e1..5e1f31b 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -22,10 +22,10 @@ Optional properties:
 				width of 8 is assumed.
 
  - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-
-		"sw"		Software method (default)
-		"hw"		Hardware method
-		"hw-romcode"	gpmc hamming mode method & romcode layout
+		"sw"		<deprecated> use "ham1" instead
+		"hw"		<deprecated> use "ham1" instead
+		"hw-romcode"	<deprecated> use "ham1" instead
+		"ham1"		1-bit Hamming ecc code
 		"bch4"		4-bit BCH ecc code
 		"bch8"		8-bit BCH ecc code
 
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index fc20a61..ac82512 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
 
-	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
 	gpmc_nand_init(&board_nand_data, gpmc_t);
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..8d521aa 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1993,10 +1993,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
-		info->nand.ecc.mode = NAND_ECC_SOFT;
-	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
-		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 		info->nand.ecc.bytes            = 3;
 		info->nand.ecc.size             = 512;
 		info->nand.ecc.strength         = 1;
@@ -2025,7 +2022,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
 		if (info->nand.options & NAND_BUSWIDTH_16)
 			offset = 2;
@@ -2033,7 +2030,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			offset = 1;
 			info->nand.badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16);
+		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index e4128f1..4da5bfa 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,13 +23,8 @@ enum nand_io {
 };
 
 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 */
 	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
-	OMAP_ECC_HAM1_CODE_HW,
+	OMAP_ECC_HAM1_CODE_HW = 0,
 	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
 	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
 	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:05 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:05 +0530
Subject: [PATCH v10 01/10] ARM: OMAP2+: cleaned-up DT support of various ECC
 schemes
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-2-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in different
flavours, depending on in-build Hardware engines present on SoC.

This patch updates following in DT bindings related to sectionion of ecc-schemes
- ti,elm-id: replaces elm_id (maintains backward compatibility)
- ti,nand-ecc-opts: selection of h/w or s/w implementation of an ecc-scheme
	depends on ti,elm-id. (supported values ham1, bch4, and bch8)
- maintain backward compatibility to deprecated DT bindings (sw, hw, hw-romcode)

Below table shows different flavours of ecc-schemes supported by OMAP devices
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+

To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
 arch/arm/mach-omap2/gpmc.c                         | 48 +++++++++++++++-------
 include/linux/platform_data/mtd-nand-omap2.h       | 13 +++++-
 3 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index df338cb..bfe07e1 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -36,8 +36,12 @@ Optional properties:
 		"prefetch-dma"		Prefetch enabled sDMA mode
 		"prefetch-irq"		Prefetch enabled irq mode
 
- - elm_id:	Specifies elm device node. This is required to support BCH
- 		error correction using ELM module.
+ - elm_id:	<deprecated> use "ti,elm-id" instead
+ - ti,elm-id:	Specifies phandle of the ELM devicetree node.
+		ELM is an on-chip hardware engine on TI SoC which is used for
+		locating ECC errors for BCHx algorithms. SoC devices which have
+		ELM hardware engines should specify this device node in .dtsi
+		Using ELM for ECC error correction frees some CPU cycles.
 
 For inline partiton table parsing (optional):
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 579697a..c877129 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1341,14 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 
 #ifdef CONFIG_MTD_NAND
 
-static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
-	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
-	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
-	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
-	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
-};
-
 static const char * const nand_xfer_types[] = {
 	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
 	[NAND_OMAP_POLLED]			= "polled",
@@ -1378,13 +1370,41 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 	gpmc_nand_data->cs = val;
 	gpmc_nand_data->of_node = child;
 
-	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-			if (!strcasecmp(s, nand_ecc_opts[val])) {
-				gpmc_nand_data->ecc_opt = val;
-				break;
-			}
+	/* Detect availability of ELM module */
+	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		gpmc_nand_data->elm_of_node =
+					of_parse_phandle(child, "elm_id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		pr_warn("%s: ti,elm-id property not found\n", __func__);
+
+	/* select ecc-scheme for NAND */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!strcmp(s, "ham1") || !strcmp(s, "sw") ||
+		!strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
+		gpmc_nand_data->ecc_opt =
+				OMAP_ECC_HAM1_CODE_HW;
+	else if (!strcmp(s, "bch4"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	else if (!strcmp(s, "bch8"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	else
+		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
 
+	/* select data transfer mode for NAND controller */
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
 		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
 			if (!strcasecmp(s, nand_xfer_types[val])) {
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 6bf9ef4..e4128f1 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -28,8 +28,16 @@ enum omap_ecc {
 	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 */
+	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_HAM1_CODE_HW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH4_CODE_HW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH8_CODE_HW,
 };
 
 struct gpmc_nand_regs {
@@ -63,5 +71,6 @@ struct omap_nand_platform_data {
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
+	struct device_node	*elm_of_node;
 };
 #endif
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:07 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:07 +0530
Subject: [PATCH v10 03/10] mtd: nand: omap: cleanup: replace local references
 with generic framework names
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-4-git-send-email-pekon@ti.com>

This patch updates following in omap_nand_probe() and omap_nand_remove()
- replaces "info->nand" with "nand_chip" (struct nand_chip *nand_chip)
- replaces "info->mtd" with "mtd" (struct mtd_info *mtd)
- white-space and formatting cleanup

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 112 ++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 55 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8d521aa..5596368 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1824,10 +1824,12 @@ static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
 	struct omap_nand_platform_data	*pdata;
+	struct mtd_info			*mtd;
+	struct nand_chip		*nand_chip;
 	int				err;
 	int				i, offset;
-	dma_cap_mask_t mask;
-	unsigned sig;
+	dma_cap_mask_t			mask;
+	unsigned			sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
 
@@ -1846,17 +1848,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	spin_lock_init(&info->controller.lock);
 	init_waitqueue_head(&info->controller.wq);
 
-	info->pdev = pdev;
-
+	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-
-	info->mtd.priv		= &info->nand;
-	info->mtd.name		= dev_name(&pdev->dev);
-	info->mtd.owner		= THIS_MODULE;
-
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
+	mtd			= &info->mtd;
+	mtd->priv		= &info->nand;
+	mtd->name		= dev_name(&pdev->dev);
+	mtd->owner		= THIS_MODULE;
+	nand_chip		= &info->nand;
+	nand_chip->options	= pdata->devsize;
+	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
 #endif
@@ -1877,16 +1878,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_free_info;
 	}
 
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
-	if (!info->nand.IO_ADDR_R) {
+	nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	if (!nand_chip->IO_ADDR_R) {
 		err = -ENOMEM;
 		goto out_release_mem_region;
 	}
 
-	info->nand.controller = &info->controller;
+	nand_chip->controller = &info->controller;
 
-	info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
-	info->nand.cmd_ctrl  = omap_hwcontrol;
+	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
+	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
@@ -1896,26 +1897,26 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * device and read status register until you get a failure or success
 	 */
 	if (pdata->dev_ready) {
-		info->nand.dev_ready = omap_dev_ready;
-		info->nand.chip_delay = 0;
+		nand_chip->dev_ready = omap_dev_ready;
+		nand_chip->chip_delay = 0;
 	} else {
-		info->nand.waitfunc = omap_wait;
-		info->nand.chip_delay = 50;
+		nand_chip->waitfunc = omap_wait;
+		nand_chip->chip_delay = 50;
 	}
 
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
-		info->nand.read_buf   = omap_read_buf_pref;
-		info->nand.write_buf  = omap_write_buf_pref;
+		nand_chip->read_buf   = omap_read_buf_pref;
+		nand_chip->write_buf  = omap_write_buf_pref;
 		break;
 
 	case NAND_OMAP_POLLED:
-		if (info->nand.options & NAND_BUSWIDTH_16) {
-			info->nand.read_buf   = omap_read_buf16;
-			info->nand.write_buf  = omap_write_buf16;
+		if (nand_chip->options & NAND_BUSWIDTH_16) {
+			nand_chip->read_buf   = omap_read_buf16;
+			nand_chip->write_buf  = omap_write_buf16;
 		} else {
-			info->nand.read_buf   = omap_read_buf8;
-			info->nand.write_buf  = omap_write_buf8;
+			nand_chip->read_buf   = omap_read_buf8;
+			nand_chip->write_buf  = omap_write_buf8;
 		}
 		break;
 
@@ -1944,8 +1945,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 					err);
 				goto out_release_mem_region;
 			}
-			info->nand.read_buf   = omap_read_buf_dma_pref;
-			info->nand.write_buf  = omap_write_buf_dma_pref;
+			nand_chip->read_buf   = omap_read_buf_dma_pref;
+			nand_chip->write_buf  = omap_write_buf_dma_pref;
 		}
 		break;
 
@@ -1980,8 +1981,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 			goto out_release_mem_region;
 		}
 
-		info->nand.read_buf  = omap_read_buf_irq_pref;
-		info->nand.write_buf = omap_write_buf_irq_pref;
+		nand_chip->read_buf  = omap_read_buf_irq_pref;
+		nand_chip->write_buf = omap_write_buf_irq_pref;
 
 		break;
 
@@ -1994,16 +1995,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	/* select the ecc type */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-		info->nand.ecc.bytes            = 3;
-		info->nand.ecc.size             = 512;
-		info->nand.ecc.strength         = 1;
-		info->nand.ecc.calculate        = omap_calculate_ecc;
-		info->nand.ecc.hwctl            = omap_enable_hwecc;
-		info->nand.ecc.correct          = omap_correct_data;
-		info->nand.ecc.mode             = NAND_ECC_HW;
+		nand_chip->ecc.bytes            = 3;
+		nand_chip->ecc.size             = 512;
+		nand_chip->ecc.strength         = 1;
+		nand_chip->ecc.calculate        = omap_calculate_ecc;
+		nand_chip->ecc.hwctl            = omap_enable_hwecc;
+		nand_chip->ecc.correct          = omap_correct_data;
+		nand_chip->ecc.mode             = NAND_ECC_HW;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(&info->mtd, pdata->ecc_opt);
+		err = omap3_init_bch(mtd, pdata->ecc_opt);
 		if (err) {
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2013,9 +2014,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 	/* DIP switches on some boards change between 8 and 16 bit
 	 * bus widths for flash.  Try the other width if the first try fails.
 	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		nand_chip->options ^= NAND_BUSWIDTH_16;
+		if (nand_scan_ident(mtd, 1, NULL)) {
 			err = -ENXIO;
 			goto out_release_mem_region;
 		}
@@ -2024,25 +2025,25 @@ static int omap_nand_probe(struct platform_device *pdev)
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
-		if (info->nand.options & NAND_BUSWIDTH_16)
+		if (nand_chip->options & NAND_BUSWIDTH_16) {
 			offset = 2;
-		else {
+		} else {
 			offset = 1;
-			info->nand.badblock_pattern = &bb_descrip_flashbased;
+			nand_chip->badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
+		omap_oobinfo.eccbytes = 3 * (mtd->writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
 		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = info->mtd.oobsize -
+		omap_oobinfo.oobfree->length = mtd->oobsize -
 					(offset + omap_oobinfo.eccbytes);
 
-		info->nand.ecc.layout = &omap_oobinfo;
+		nand_chip->ecc.layout = &omap_oobinfo;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
 		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(&info->mtd);
+		err = omap3_init_bch_tail(mtd);
 		if (err) {
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2050,16 +2051,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* second phase scan */
-	if (nand_scan_tail(&info->mtd)) {
+	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
 		goto out_release_mem_region;
 	}
 
 	ppdata.of_node = pdata->of_node;
-	mtd_device_parse_register(&info->mtd, NULL, &ppdata, pdata->parts,
+	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
 				  pdata->nr_parts);
 
-	platform_set_drvdata(pdev, &info->mtd);
+	platform_set_drvdata(pdev, mtd);
 
 	return 0;
 
@@ -2080,9 +2081,10 @@ out_free_info:
 static int omap_nand_remove(struct platform_device *pdev)
 {
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(&info->mtd);
+	omap3_free_bch(mtd);
 
 	if (info->dma)
 		dma_release_channel(info->dma);
@@ -2093,8 +2095,8 @@ static int omap_nand_remove(struct platform_device *pdev)
 		free_irq(info->gpmc_irq_fifo, info);
 
 	/* Release NAND device, its internal structures and partitions */
-	nand_release(&info->mtd);
-	iounmap(info->nand.IO_ADDR_R);
+	nand_release(mtd);
+	iounmap(nand_chip->IO_ADDR_R);
 	release_mem_region(info->phys_base, info->mem_size);
 	kfree(info);
 	return 0;
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:08 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:08 +0530
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan: NAND_CMD_READID,
 NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-5-git-send-email-pekon@ti.com>

As per comments below, NAND_CMD_RESET, NAND_CMD_READID, and NAND_CMD_PARAM would
work only in x8 mode.
    commit 64b37b2a63eb2f80b65c7185f0013f8ffc637ae3
    Author:     Matthieu CASTET <matthieu.castet at parrot.com>
    AuthorDate: 2012-11-06
    Note that nand_scan_ident send command (NAND_CMD_RESET, NAND_CMD_READID, NAND_CMD_PARAM), address and read data
    The ONFI specificication is not very clear for x16 device if high byte of address should be driven to 0,
    but according to [1] it should be ok to not drive it during autodetection.

    [1]
    3.3.2. Target Initialization

    [...]
    The Read ID and Read Parameter Page commands only use the lower 8-bits of the data bus.
    The host shall not issue commands that use a word data width on x16 devices until the host
    determines the device supports a 16-bit data bus width in the parameter page.

Thus this patch run nand_scan_ident() with driver configured as x8 device.
Once the NAND device is detected, and its ONFI params are read, the driver
is re-configured based on device-width as passed by DT bindinig 'nand-bus-width'

In-case there is a mis-match between the DT binding 'nand-bus-width' and actual
device-width detected during nand_get_flash_type() then probe returns failure.

All other low-level callback updates happen after the device detection.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 45 +++++++++++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5596368..d29edda 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
-	nand_chip->options	= pdata->devsize;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
@@ -1904,6 +1903,39 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->chip_delay = 50;
 	}
 
+	/* scan NAND device connected to chip controller */
+	/* configure driver in x8 mode to read ONFI parameter page, as
+	 * NAND_CMD_READID & NAND_CMD_PARAM may not work in x16 mode */
+	nand_chip->options &= ~NAND_BUSWIDTH_16;
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		/* nand_scan_ident failed */
+		if (pdata->devsize) {
+			/* may be because of mis-match of device-width,
+			 * platform data (DT binding) also says its x16 device
+			 * So re-scan with proper device-width */
+			nand_chip->options |= pdata->devsize;
+			if (nand_scan_ident(mtd, 1, NULL)) {
+				err = -ENXIO;
+				goto out_release_mem_region;
+			}
+		} else {
+			/* some genuine failure, because even platform-data
+			 * (DT binding) says that bus-width is x8 */
+			err = -ENXIO;
+			goto out_release_mem_region;
+		}
+	} else {
+		/* nand_scan_ident passed with x8 mode */
+		if (pdata->devsize) {
+			/* but platform-data (DT binding) say its x16 device */
+			pr_err("%s: incorrect bus-width config\n", DRIVER_NAME);
+			err = -EINVAL;
+			err = -ENXIO;
+			goto out_release_mem_region;
+		}
+	}
+
+	/* re-populate low-level callbacks based on xfer modes */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		nand_chip->read_buf   = omap_read_buf_pref;
@@ -2011,17 +2043,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(mtd, 1, NULL)) {
-		nand_chip->options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(mtd, 1, NULL)) {
-			err = -ENXIO;
-			goto out_release_mem_region;
-		}
-	}
-
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:10 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:10 +0530
Subject: [PATCH v10 06/10] mtd: nand: omap: clean-up ecc layout for BCH ecc
 schemes
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-7-git-send-email-pekon@ti.com>

In current implementation omap3_init_bch_tail() is a common function to
define ecc layout for different BCHx ecc schemes.This patch:
(1) removes omap3_init_bch_tail() and defines ecc layout for individual
    ecc-schemes along with populating their nand_chip->ecc data in
    omap_nand_probe(). This improves the readability and scalability of
    code for add new ecc schemes in future.
(2) removes 'struct nand_bbt_descr bb_descrip_flashbased' because default
    nand_bbt_descr in nand_bbt.c matches the same (.len=1 for x8 devices).
(3) add the check to see if NAND device has enough OOB/Spare bytes to
    store ECC signature of whole page, as defined by ecc-scheme.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 161 ++++++++++++++++++-----------------------------
 1 file changed, 62 insertions(+), 99 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 978240b..c93655e 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -139,6 +139,7 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define BADBLOCK_MARKER_LENGTH		2
 #define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
@@ -149,17 +150,6 @@ static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
 
 /* 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
- * while scanning a device for factory marked good / bad blocks
- */
-static uint8_t scan_ff_pattern[] = { 0xff };
-static struct nand_bbt_descr bb_descrip_flashbased = {
-	.options = NAND_BBT_SCANALLPAGES,
-	.offs = 0,
-	.len = 1,
-	.pattern = scan_ff_pattern,
-};
-
 
 struct omap_nand_info {
 	struct nand_hw_control		controller;
@@ -184,7 +174,6 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct bch_control             *bch;
-	struct nand_ecclayout           ecclayout;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1686,65 +1675,8 @@ static void omap3_free_bch(struct mtd_info *mtd)
 	}
 }
 
-/**
- * omap3_init_bch_tail - Build an oob layout for BCH ECC correction.
- * @mtd: MTD device structure
- */
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	int i, steps, offset;
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	struct nand_ecclayout *layout = &info->ecclayout;
-
-	/* build oob layout */
-	steps = mtd->writesize/info->nand.ecc.size;
-	layout->eccbytes = steps*info->nand.ecc.bytes;
-
-	/* do not bother creating special oob layouts for small page devices */
-	if (mtd->oobsize < 64) {
-		pr_err("BCH ecc is not supported on small page devices\n");
-		goto fail;
-	}
-
-	/* reserve 2 bytes for bad block marker */
-	if (layout->eccbytes+2 > mtd->oobsize) {
-		pr_err("no oob layout available for oobsize %d eccbytes %u\n",
-		       mtd->oobsize, layout->eccbytes);
-		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] = 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].length = mtd->oobsize-2-layout->eccbytes;
-	info->nand.ecc.layout = layout;
-
-	if (!(info->nand.options & NAND_BUSWIDTH_16))
-		info->nand.badblock_pattern = &bb_descrip_flashbased;
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
-}
-
 #else
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	return -1;
-}
+
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
@@ -1756,8 +1688,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 	struct omap_nand_platform_data	*pdata;
 	struct mtd_info			*mtd;
 	struct nand_chip		*nand_chip;
+	struct nand_ecclayout		*ecclayout;
 	int				err;
-	int				i, offset;
+	int				i;
 	dma_cap_mask_t			mask;
 	unsigned			sig;
 	struct resource			*res;
@@ -1864,6 +1797,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		}
 	}
 
+	/* check for small page devices */
+	if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
+		pr_err("small page devices are not supported\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
 	/* re-populate low-level callbacks based on xfer modes */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
@@ -1955,6 +1895,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* populate MTD interface based on ECC scheme */
+	nand_chip->ecc.layout	= &omap_oobinfo;
+	ecclayout		= &omap_oobinfo;
 	switch (pdata->ecc_opt) {
 	case OMAP_ECC_HAM1_CODE_HW:
 		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
@@ -1965,6 +1907,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.calculate        = omap_calculate_ecc;
 		nand_chip->ecc.hwctl            = omap_enable_hwecc;
 		nand_chip->ecc.correct          = omap_correct_data;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		if (nand_chip->options & NAND_BUSWIDTH_16)
+			ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
+		else
+			ecclayout->eccpos[0]	= 1;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		break;
 
 	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
@@ -1977,6 +1929,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap3_correct_data_bch;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
 		info->bch = init_bch(nand_chip->ecc.bytes,
 					nand_chip->ecc.strength,
@@ -2005,6 +1964,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
@@ -2028,6 +1994,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap3_correct_data_bch;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
 		info->bch = init_bch(nand_chip->ecc.bytes,
 					nand_chip->ecc.strength,
@@ -2062,6 +2035,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 			pr_err("nand: error: could not initialize ELM\n");
 			goto out_release_mem_region;
 		}
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
@@ -2075,34 +2055,17 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-
-		if (nand_chip->options & NAND_BUSWIDTH_16) {
-			offset = 2;
-		} else {
-			offset = 1;
-			nand_chip->badblock_pattern = &bb_descrip_flashbased;
-		}
-		omap_oobinfo.eccbytes = 3 * (mtd->writesize / 512);
-		for (i = 0; i < omap_oobinfo.eccbytes; i++)
-			omap_oobinfo.eccpos[i] = i+offset;
-
-		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = mtd->oobsize -
-					(offset + omap_oobinfo.eccbytes);
-
-		nand_chip->ecc.layout = &omap_oobinfo;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(mtd);
-		if (err) {
-			err = -EINVAL;
-			goto out_release_mem_region;
-		}
+	/* populate remaining ECC layout data */
+	ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH +
+							ecclayout->eccbytes);
+	for (i = 1; i < ecclayout->eccbytes; i++)
+		ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
+	/* check if NAND device's OOB is enough to store ECC signatures */
+	if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
+		pr_err("not enough OOB bytes required = %d, available=%d\n",
+					   ecclayout->eccbytes, mtd->oobsize);
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* second phase scan */
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:09 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:09 +0530
Subject: [PATCH v10 05/10] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-6-git-send-email-pekon@ti.com>

current implementation in omap3_init_bch() has some redundant code like:
(1) omap3_init_bch() re-probes the DT-binding to detect presence of ELM h/w
    engine on SoC. And based on that it selects implemetation of ecc-scheme.
    However, this is already done as part of GPMC DT parsing.
(2) As omap3_init_bch() serves as common function for configuring all types of
    BCHx ecc-schemes, so there are multiple levels of redudant if..then..else
    checks while populating nand_chip->ecc.

This patch make following changes to OMAP NAND driver:
(1) removes omap3_init_bch(): each ecc-scheme is individually configured in
    omap_nand_probe() there by removing redundant if..then..else checks.
(2) adds is_elm_present(): re-probing of ELM device via DT is not required as
    it's done in GPMC driver probe. Thus is_elm_present() just initializes ELM
    driver with NAND probe data, when ecc-scheme with h/w based error-detection
    is used.
(3) separates out configuration of different flavours of "BCH4" and "BCH8"
    ecc-schemes as given in below table
(4) conditionally compiles callbacks implementations of ecc.hwctl(),
    ecc.calculate(), ecc.correct() to avoid warning of un-used functions.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+

- 'CONFIG_MTD_NAND_ECC_BCH' is generic KConfig required to build lib/bch.c
    which is required for ECC error detection done in software.
    (mainly used for legacy platforms which do not have on-chip ELM engine)

- 'CONFIG_MTD_NAND_OMAP_BCH' is OMAP specific Kconfig to detemine presence
    on ELM h/w engine on SoC.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 281 ++++++++++++++++++++++++++---------------------
 1 file changed, 158 insertions(+), 123 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index d29edda..978240b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,10 +25,8 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/bch.h>
 #include <linux/platform_data/elm.h>
-#endif
 
 #include <linux/platform_data/mtd-nand-omap2.h>
 
@@ -141,6 +139,8 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
+
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 	0xac, 0x6b, 0xff, 0x99, 0x7b};
@@ -182,14 +182,12 @@ struct omap_nand_info {
 	u_char				*buf;
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	/* fields specific for BCHx_HW ECC scheme */
 	struct bch_control             *bch;
 	struct nand_ecclayout           ecclayout;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
-#endif
 };
 
 /**
@@ -1058,8 +1056,7 @@ static int omap_dev_ready(struct mtd_info *mtd)
 	}
 }
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
  * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
  * @mtd: MTD device structure
@@ -1140,7 +1137,9 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	/* Clear ecc and enable bits */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
+#endif
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
  * @mtd: MTD device structure
@@ -1225,7 +1224,9 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 
 	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1517,7 +1518,9 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
+#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_correct_data_bch - Decode received data and correct errors
  * @mtd: MTD device structure
@@ -1549,7 +1552,9 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
 	}
 	return count;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1637,118 +1642,48 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
+ * is_elm_present - checks for presence of ELM module by scanning DT nodes
+ * @omap_nand_info: NAND device structure containing platform data
+ * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16
  */
-static void omap3_free_bch(struct mtd_info *mtd)
+static int is_elm_present(struct omap_nand_info *info,
+			struct device_node *elm_node, enum bch_ecc bch_type)
 {
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
+	struct platform_device *pdev;
+	info->is_elm_used = false;
+	/* check whether elm-id is passed via DT */
+	if (!elm_node) {
+		pr_err("nand: error: ELM DT node not found\n");
+		return -ENODEV;
+	}
+	pdev = of_find_device_by_node(elm_node);
+	/* check whether ELM device is registered */
+	if (!pdev) {
+		pr_err("nand: error: ELM device not found\n");
+		return -ENODEV;
 	}
+	/* ELM module available, now configure it */
+	info->elm_dev = &pdev->dev;
+	if (elm_config(info->elm_dev, bch_type))
+		return -ENODEV;
+	info->is_elm_used = true;
+	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
- * omap3_init_bch - Initialize BCH ECC
+ * omap3_free_bch - Release BCH ecc resources
  * @mtd: MTD device structure
- * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW)
  */
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
+static void omap3_free_bch(struct mtd_info *mtd)
 {
-	int max_errors;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-#ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = BCH8_MAX_ERROR;
-#else
-	const int hw_errors = BCH4_MAX_ERROR;
-#endif
-	enum bch_ecc bch_type;
-	const __be32 *parp;
-	int lenp;
-	struct device_node *elm_node;
-
-	info->bch = NULL;
-
-	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);
-		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 = max_errors;
-
-	if (hw_errors == BCH8_MAX_ERROR)
-		bch_type = BCH8_ECC;
-	else
-		bch_type = BCH4_ECC;
-
-	/* Detect availability of ELM module */
-	parp = of_get_property(info->of_node, "elm_id", &lenp);
-	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
-		pr_err("Missing elm_id property, fall back to Software BCH\n");
-		info->is_elm_used = false;
-	} else {
-		struct platform_device *pdev;
-
-		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
-		pdev = of_find_device_by_node(elm_node);
-		info->elm_dev = &pdev->dev;
-
-		if (elm_config(info->elm_dev, bch_type) == 0)
-			info->is_elm_used = true;
-	}
-
-	if (info->is_elm_used && (mtd->writesize <= 4096)) {
-
-		if (hw_errors == BCH8_MAX_ERROR)
-			info->nand.ecc.bytes = BCH8_SIZE;
-		else
-			info->nand.ecc.bytes = BCH4_SIZE;
-
-		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;
-	} else {
-		/*
-		 * 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;
-		}
+	if (info->bch) {
+		free_bch(info->bch);
+		info->bch = NULL;
 	}
-
-	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
 
 /**
@@ -1806,11 +1741,6 @@ fail:
 }
 
 #else
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n");
-	return -1;
-}
 static int omap3_init_bch_tail(struct mtd_info *mtd)
 {
 	return -1;
@@ -1818,7 +1748,7 @@ static int omap3_init_bch_tail(struct mtd_info *mtd)
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
 static int omap_nand_probe(struct platform_device *pdev)
 {
@@ -1851,15 +1781,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
+	info->bch		= NULL;
+	info->of_node		= pdata->of_node;
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN;
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-	info->of_node		= pdata->of_node;
-#endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
@@ -2025,22 +1954,125 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
+	/* populate MTD interface based on ECC scheme */
+	switch (pdata->ecc_opt) {
+	case OMAP_ECC_HAM1_CODE_HW:
+		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
+		nand_chip->ecc.mode             = NAND_ECC_HW;
 		nand_chip->ecc.bytes            = 3;
 		nand_chip->ecc.size             = 512;
 		nand_chip->ecc.strength         = 1;
 		nand_chip->ecc.calculate        = omap_calculate_ecc;
 		nand_chip->ecc.hwctl            = omap_enable_hwecc;
 		nand_chip->ecc.correct          = omap_correct_data;
-		nand_chip->ecc.mode             = NAND_ECC_HW;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(mtd, pdata->ecc_opt);
-		if (err) {
+		break;
+
+	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 7;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH4_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 7 + 1;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			err = -ENODEV;
 			goto out_release_mem_region;
 		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 13;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
+			err = -EINVAL;
+			goto out_release_mem_region;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH8_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 13 + 1;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			goto out_release_mem_region;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	default:
+		pr_err("nand: error: invalid or unsupported ECC scheme\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* rom code layout */
@@ -2062,6 +2094,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 		nand_chip->ecc.layout = &omap_oobinfo;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
+		   (pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) ||
+		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
 		/* build OOB layout for BCH ECC correction */
 		err = omap3_init_bch_tail(mtd);
@@ -2094,6 +2128,7 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
+	omap3_free_bch(mtd);
 	kfree(info);
 
 	return err;
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:11 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:11 +0530
Subject: [PATCH v10 07/10] mtd: nand: omap: use drivers/mtd/nand/nand_bch.c
 wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-8-git-send-email-pekon@ti.com>

generic frame-work in mtd/nand/nand_bch.c is a wrapper above lib/bch.h which
encapsulates all control information specific to BCH ecc algorithm in software.
Thus this patch:
(1) replace omap specific implementations with equivalent wrapper in nand_bch.c
    so that generic code from nand_bch.c is re-used. like;
        omap3_correct_data_bch() -> nand_bch_correct_data()
        omap3_free_bch() -> nand_bch_free()
(2) replace direct calls to lib/bch.c with wrapper functions defined in nand_bch.c
	init_bch() -> nand_bch_init()

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 96 +++++++++++-------------------------------------
 1 file changed, 22 insertions(+), 74 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c93655e..4f8efe0 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,7 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#include <linux/bch.h>
+#include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
@@ -140,7 +140,6 @@
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
 #define BADBLOCK_MARKER_LENGTH		2
-#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
@@ -173,7 +172,6 @@ struct omap_nand_info {
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
-	struct bch_control             *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1507,43 +1505,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_correct_data_bch - Decode received data and correct errors
- * @mtd: MTD device structure
- * @data: page data
- * @read_ecc: ecc read from nand flash
- * @calc_ecc: ecc read from HW ECC registers
- */
-static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
-				  u_char *read_ecc, u_char *calc_ecc)
-{
-	int i, count;
-	/* cannot correct more than 8 errors */
-	unsigned int errloc[8];
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-
-	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
-			   errloc);
-	if (count > 0) {
-		/* correct errors */
-		for (i = 0; i < count; i++) {
-			/* correct data only, not ecc bytes */
-			if (errloc[i] < 8*512)
-				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
-			pr_debug("corrected bitflip %u\n", errloc[i]);
-		}
-	} else if (count < 0) {
-		pr_err("ecc unrecoverable error\n");
-	}
-	return count;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1660,28 +1622,6 @@ static int is_elm_present(struct omap_nand_info *info,
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
- */
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-#else
-
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
@@ -1714,13 +1654,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-	info->bch		= NULL;
 	info->of_node		= pdata->of_node;
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
+	nand_chip->ecc.priv	= NULL;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1927,7 +1867,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1937,10 +1877,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		nand_chip->ecc.priv		= nand_bch_init(mtd,
+							nand_chip->ecc.size,
+							nand_chip->ecc.bytes,
+							&nand_chip->ecc.layout);
+		if (!nand_chip->ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 		}
@@ -1992,7 +1933,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -2002,10 +1943,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		nand_chip->ecc.priv		= nand_bch_init(mtd,
+							nand_chip->ecc.size,
+							nand_chip->ecc.bytes,
+							&nand_chip->ecc.layout);
+		if (!nand_chip->ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2091,7 +2033,10 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
-	omap3_free_bch(mtd);
+	if (nand_chip->ecc.priv) {
+		nand_bch_free(nand_chip->ecc.priv);
+		nand_chip->ecc.priv = NULL;
+	}
 	kfree(info);
 
 	return err;
@@ -2103,7 +2048,10 @@ static int omap_nand_remove(struct platform_device *pdev)
 	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(mtd);
+	if (nand_chip->ecc.priv) {
+		nand_bch_free(nand_chip->ecc.priv);
+		nand_chip->ecc.priv = NULL;
+	}
 
 	if (info->dma)
 		dma_release_channel(info->dma);
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:12 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:12 +0530
Subject: [PATCH v10 08/10] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-9-git-send-email-pekon@ti.com>

Updated DTS to replace deprecated binding with newer values
Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/boot/dts/am335x-evm.dts   | 3 +--
 arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e8ec875..1aee6ac 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -269,7 +269,6 @@
 				reg = <0 0 0>; /* CS0, offset 0 */
 				nand-bus-width = <8>;
 				ti,nand-ecc-opt = "bch8";
-				gpmc,device-nand = "true";
 				gpmc,device-width = <1>;
 				gpmc,sync-clk-ps = <0>;
 				gpmc,cs-on-ns = <0>;
@@ -296,7 +295,7 @@
 
 				#address-cells = <1>;
 				#size-cells = <1>;
-				elm_id = <&elm>;
+				ti,elm-id = <&elm>;
 
 				/* MTD partition table */
 				partition at 0 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index e2249bc..501f863 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -105,7 +105,7 @@
 		reg = <1 0 0x08000000>;
 		nand-bus-width = <8>;
 
-		ti,nand-ecc-opt = "sw";
+		ti,nand-ecc-opt = "ham1";
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <36>;
 		gpmc,cs-wr-off-ns = <36>;
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:13 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:13 +0530
Subject: [PATCH v10 09/10] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-10-git-send-email-pekon@ti.com>

"Managed Device Resource" or devm_xx calls takes care of automatic freeing
of the resource in case of:
- failure during driver probe
- failure during resource allocation
- detaching or unloading of driver module (rmmod)
Reference: Documentation/driver-model/devres.txt

Though OMAP NAND driver handles freeing of resource allocation in most of
the cases, but using devm_xx provides more clean and effortless approach
to handle all such cases.

- simplifies label for exiting probe during error
  s/out_release_mem_region/return_error

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 89 ++++++++++++++++++++----------------------------
 1 file changed, 37 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4f8efe0..45433f4 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1642,7 +1642,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
+				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -1667,22 +1668,23 @@ static int omap_nand_probe(struct platform_device *pdev)
 	if (res == NULL) {
 		err = -EINVAL;
 		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto out_free_info;
+		goto return_error;
 	}
 
 	info->phys_base = res->start;
 	info->mem_size = resource_size(res);
 
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
+	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
+				info->mem_size,	pdev->dev.driver->name)) {
 		err = -EBUSY;
-		goto out_free_info;
+		goto return_error;
 	}
 
-	nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	nand_chip->IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
+						info->mem_size);
 	if (!nand_chip->IO_ADDR_R) {
 		err = -ENOMEM;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	nand_chip->controller = &info->controller;
@@ -1718,13 +1720,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 			nand_chip->options |= pdata->devsize;
 			if (nand_scan_ident(mtd, 1, NULL)) {
 				err = -ENXIO;
-				goto out_release_mem_region;
+				goto return_error;
 			}
 		} else {
 			/* some genuine failure, because even platform-data
 			 * (DT binding) says that bus-width is x8 */
 			err = -ENXIO;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 	} else {
 		/* nand_scan_ident passed with x8 mode */
@@ -1733,7 +1735,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			pr_err("%s: incorrect bus-width config\n", DRIVER_NAME);
 			err = -EINVAL;
 			err = -ENXIO;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 	}
 
@@ -1741,7 +1743,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
 		pr_err("small page devices are not supported\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* re-populate low-level callbacks based on xfer modes */
@@ -1769,7 +1771,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (!info->dma) {
 			dev_err(&pdev->dev, "DMA engine request failed\n");
 			err = -ENXIO;
-			goto out_release_mem_region;
+			goto return_error;
 		} else {
 			struct dma_slave_config cfg;
 
@@ -1784,7 +1786,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			if (err) {
 				dev_err(&pdev->dev, "DMA engine slave config failed: %d\n",
 					err);
-				goto out_release_mem_region;
+				goto return_error;
 			}
 			nand_chip->read_buf   = omap_read_buf_dma_pref;
 			nand_chip->write_buf  = omap_write_buf_dma_pref;
@@ -1796,30 +1798,32 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (info->gpmc_irq_fifo <= 0) {
 			dev_err(&pdev->dev, "error getting fifo irq\n");
 			err = -ENODEV;
-			goto out_release_mem_region;
+			goto return_error;
 		}
-		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-fifo", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-fifo", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_fifo, err);
 			info->gpmc_irq_fifo = 0;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 
 		info->gpmc_irq_count = platform_get_irq(pdev, 1);
 		if (info->gpmc_irq_count <= 0) {
 			dev_err(&pdev->dev, "error getting count irq\n");
 			err = -ENODEV;
-			goto out_release_mem_region;
+			goto return_error;
 		}
-		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-count", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-count", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_count, err);
 			info->gpmc_irq_count = 0;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 
 		nand_chip->read_buf  = omap_read_buf_irq_pref;
@@ -1831,7 +1835,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev,
 			"xfer_type(%d) not supported!\n", pdata->xfer_type);
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* populate MTD interface based on ECC scheme */
@@ -1889,7 +1893,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	case OMAP_ECC_BCH4_CODE_HW:
@@ -1916,13 +1920,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
 			err = -ENODEV;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
@@ -1950,13 +1954,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (!nand_chip->ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	case OMAP_ECC_BCH8_CODE_HW:
@@ -1975,7 +1979,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
-			goto out_release_mem_region;
+			goto return_error;
 		}
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1988,13 +1992,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	default:
 		pr_err("nand: error: invalid or unsupported ECC scheme\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* populate remaining ECC layout data */
@@ -2007,13 +2011,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		pr_err("not enough OOB bytes required = %d, available=%d\n",
 					   ecclayout->eccbytes, mtd->oobsize);
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* second phase scan */
 	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	ppdata.of_node = pdata->of_node;
@@ -2024,21 +2028,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	return 0;
 
-out_release_mem_region:
+return_error:
 	if (info->dma)
 		dma_release_channel(info->dma);
-	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
-	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
-out_free_info:
 	if (nand_chip->ecc.priv) {
 		nand_bch_free(nand_chip->ecc.priv);
 		nand_chip->ecc.priv = NULL;
 	}
-	kfree(info);
-
 	return err;
 }
 
@@ -2052,20 +2048,9 @@ static int omap_nand_remove(struct platform_device *pdev)
 		nand_bch_free(nand_chip->ecc.priv);
 		nand_chip->ecc.priv = NULL;
 	}
-
 	if (info->dma)
 		dma_release_channel(info->dma);
-
-	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
-	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-
-	/* Release NAND device, its internal structures and partitions */
 	nand_release(mtd);
-	iounmap(nand_chip->IO_ADDR_R);
-	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
 	return 0;
 }
 
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 04:44:14 2013
From: pekon at ti.com (Pekon Gupta)
Date: Sat, 19 Oct 2013 14:14:14 +0530
Subject: [PATCH v10 10/10] mtd: nand: omap: remove selection of BCH ecc-scheme
 via KConfig
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <1382172254-12448-11-git-send-email-pekon@ti.com>

With OMAP NAND driver updates, selection of ecc-scheme:
*DT enabled kernel*
 	depends on ti,nand-ecc-opt and ti,elm-id DT bindings.
*Non DT enabled kernel*
	depends on elm_dev and ecc-scheme passed along with platform-data
	from board file.

So, selection of ecc-scheme (BCH8 or BCH4) from KConfig can be removed

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/Kconfig | 40 ++++++----------------------------------
 1 file changed, 6 insertions(+), 34 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..93ae6a6 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -96,43 +96,15 @@ config MTD_NAND_OMAP2
 
 config MTD_NAND_OMAP_BCH
 	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
-	tristate "Enable support for hardware BCH error correction"
+	tristate "Support hardware based BCH error correction"
 	default n
 	select BCH
-	select BCH_CONST_PARAMS
 	help
-	 Support for hardware BCH error correction.
-
-choice
-	prompt "BCH error correction capability"
-	depends on MTD_NAND_OMAP_BCH
-
-config MTD_NAND_OMAP_BCH8
-	bool "8 bits / 512 bytes (recommended)"
-	help
-	 Support correcting up to 8 bitflips per 512-byte block.
-	 This will use 13 bytes of spare area per 512 bytes of page data.
-	 This is the recommended mode, as 4-bit mode does not work
-	 on some OMAP3 revisions, due to a hardware bug.
-
-config MTD_NAND_OMAP_BCH4
-	bool "4 bits / 512 bytes"
-	help
-	 Support correcting up to 4 bitflips per 512-byte block.
-	 This will use 7 bytes of spare area per 512 bytes of page data.
-	 Note that this mode does not work on some OMAP3 revisions, due to a
-	 hardware bug. Please check your OMAP datasheet before selecting this
-	 mode.
-
-endchoice
-
-if MTD_NAND_OMAP_BCH
-config BCH_CONST_M
-	default 13
-config BCH_CONST_T
-	default 4 if MTD_NAND_OMAP_BCH4
-	default 8 if MTD_NAND_OMAP_BCH8
-endif
+	  This config enables the ELM hardware engine, which can be used to
+	  locate and correct errors when using BCH ECC scheme. This offloads
+	  the cpu from doing ECC error searching and correction. However some
+	  legacy OMAP families like OMAP2xxx, OMAP3xxx do not have ELM engine
+	  so they should not enable this config symbol.
 
 config MTD_NAND_IDS
 	tristate
-- 
1.8.1



From pekon at ti.com  Sat Oct 19 05:11:39 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Sat, 19 Oct 2013 09:11:39 +0000
Subject: [PATCH v9 4/9] mtd: nand: omap: enable auto-detection of
 bus-width for omap-nand drivers
In-Reply-To: <20131017214349.GH23337@ld-irv-0074.broadcom.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-5-git-send-email-pekon@ti.com>
 <20131016222248.GZ23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27917@DBDE04.ent.ti.com>
 <20131017183016.GG23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA280A4@DBDE04.ent.ti.com>
 <20131017214349.GH23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA28D68@DBDE04.ent.ti.com>

Hi Brian,

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> On Thu, Oct 17, 2013 at 09:00:27PM +0000, Pekon Gupta wrote:
> > > From: Brian Norris [mailto:computersforpeace at gmail.com]
> > > > On Thu, Oct 17, 2013 at 04:42:23AM +0000, Pekon Gupta wrote:
 [...]

> > > But the real point: you need to clearly communicate what you are
> > > choosing in this patch. Either you want to
> > >
> > >  (1) strictly follow the buswidth provided by the platform or
> > >
> > >  (2) use the nand_base.c BUSWIDTH_AUTO automatic configuration.
> > >
> > Ideally, I would like to go with (2), but that would need other changes
> > in-order to re-configure GPMC with newly parsed ONFI data, which
> > can be a separate patch-set.
> 
> What exactly needs changed to support this? It looks like this omap2
> NAND driver doesn't make assumptions about 8-bit vs. 16-bit until after
> nand_scan_ident(). But maybe there is something I missed.
> 
The GPMC driver will be touched by NAND_BUSWIDTH_AUTO change.
There are two set of configurations in GPMC controller..
(a) device based configurations:
  These are static configurations derived on DT bindings for each
  chip-select (like NAND signal timings, etc). These done on GPMC probe.
(b) ecc-scheme based configurations:
  These are dynamic configurations done in NAND driver in
  chip->ecc.hwctl() and are refreshed at each NAND accesss.

However, 'nand-bus-width' configuration is part of both (1) and (2).
Thus, both 'OMAP NAND driver' and 'GPMC driver' need to be
consistent in programming  'nand-bus-width' otherwise ecc-engine
would not work.
Thus, I'm proceeding with (1) DT based parsing of 'nand-bus-width'.


> > Thus, I would drop this patch for now. And go with (1),
> 
> OK, but to drop this patch entirely would still not be (1); it would
> still leave the possibility of calling nand_scan_ident() twice, and it
> puts you in a middle ground between (1) and (2). That's fine if it works
> for you, but I just want to acknowledge that now: this driver requires
> changes to become either (1) or (2).
> 
I have re-posted [PATCH v10 4/10] with this updates. However, please
take into account that some limitation of dual programming require
such probe. New patch also call nand_scan_ident() twice, but only
on certain pre-determined conditions, not in all failure.
Once I convert to NAND_BUSWIDTH_AUTO these should get clean,
 as I would update both GPMC and NAND driver for this.
(Till then this was most optimal solution I could think of)..


> Does your series need a rebase if we're removing this patch? Or you're
> rewriting/simplifying it to the following two points? (Perhaps it's
> best to separate this portion to its own patch (set) and discussion,
> since it is independent of your ECC rewrite.)
> 
> > with following
> > updates in  omap_nand_probe().
> >
> > (a) perform nand_scan_ident() in "x8" mode, so that ONFI params are
> >     read and device-info (chip->writesize, chip->oobsize) are populated.
> 
> OK.
> 
> > (b) Then switch to "x8" or "x16" mode based on "nand-bus-width"
> >     as passed from GPMC driver to NAND driver via platform-data.
> >    And re-populate mtd->byte, mtd-read_buf, mtd->write_buf.
> 
> I'm not sure if switching buswidth after nand_scan_ident() is really
> supported, but I'll hold off until I see the code you're proposing.
> 
I have re-posted [PATCH v10 4/10] with this updates.
Please accept this ...


with regards, pekon


From ezequiel.garcia at free-electrons.com  Sat Oct 19 09:02:00 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 19 Oct 2013 10:02:00 -0300
Subject: [PATCH v2] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <CAN8TOE8L2jQ3nFxf5hxSw8qnFK3m4NuexbZ=yuwoS=uoFiVAnw@mail.gmail.com>
References: <1382120072-30057-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAN8TOE-hxcaj79hTxDMzP1On69n=3QdBy45fjePLrQuzSvnnyw@mail.gmail.com>
 <20131018193211.GA30464@localhost>
 <CAN8TOE8L2jQ3nFxf5hxSw8qnFK3m4NuexbZ=yuwoS=uoFiVAnw@mail.gmail.com>
Message-ID: <20131019130159.GA2470@localhost>

On Fri, Oct 18, 2013 at 06:37:06PM -0700, Brian Norris wrote:
> On Fri, Oct 18, 2013 at 12:32 PM, Ezequiel Garcia
> <ezequiel.garcia at free-electrons.com> wrote:
> > On Fri, Oct 18, 2013 at 12:15:39PM -0700, Brian Norris wrote:
> >> On Fri, Oct 18, 2013 at 11:14 AM, Ezequiel Garcia
> >> <ezequiel.garcia at free-electrons.com> wrote:
> [...]
> >> >  drivers/mtd/nand/pxa3xx_nand.c | 6 ++++--
> >> >  1 file changed, 4 insertions(+), 2 deletions(-)
> >> >
> >> > diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
> >> > index aa75adf..4d53e8e 100644
> >> > --- a/drivers/mtd/nand/pxa3xx_nand.c
> >> > +++ b/drivers/mtd/nand/pxa3xx_nand.c
> >> > @@ -46,6 +46,8 @@
> >> >   */
> >> >  #define INIT_BUFFER_SIZE       256
> >> >
> >> > +#define DRIVER_NAME            "pxa3xx_nand-0"
> >> > +
> >> >  /* registers and bit definitions */
> >> >  #define NDCR           (0x00) /* Control register */
> >> >  #define NDTR0CS0       (0x04) /* Timing Parameter 0 for CS0 */
> >> > @@ -1339,7 +1341,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
> >> >         for (cs = 0; cs < pdata->num_cs; cs++) {
> >> >                 struct mtd_info *mtd = info->host[cs]->mtd;
> >> >
> >> > -               mtd->name = pdev->name;
> >> > +               mtd->name = DRIVER_NAME;
> >> >                 info->cs = cs;
> >> >                 ret = pxa3xx_nand_scan(mtd);
> >> >                 if (ret) {
> >> > @@ -1425,7 +1427,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev)
> >> >
> >> >  static struct platform_driver pxa3xx_nand_driver = {
> >> >         .driver = {
> >> > -               .name   = "pxa3xx-nand",
> >> > +               .name   = DRIVER_NAME,
> >> >                 .of_match_table = pxa3xx_nand_dt_ids,
> >> >         },
> >> >         .probe          = pxa3xx_nand_probe,
> >>
> >> For mtdparts' sake, do we need both the driver name and the MTD name
> >> to be the same? Or could we just stick the  "pxa3xx_nand-0" directly
> >> in mtd->name only, where it's needed for compatibility, and allow the
> >> driver name to be cleaner? Or is that a silly idea?
> >>
> >
> > Hm... What's the impact of the driver's name?
> 
> I meant to ask you the exact same question, because I'm lazy :)
> 

I guess that makes the two of us lazy :)

> I'm not sure exactly. I thought it affected the device name (which is
> important to users; it's exposed in sysfs in potentially important
> ways), but that actually comes from the platform-device allocation or
> from device tree. The most visible way I know of is that it prefixes
> the messages seen via the dev_{printk,err,info,warn,..}() print
> functions. This could be annoying, but not horrible.
> 

Good point. I'm not sure my OCD will resist seeing "pxa3xx_nand-0: blabla"
printed.

> The driver name does show up in /sys/bus/platform/drivers, but I'm not
> sure if that's ever expected to be stable.
> 
> > I know it's just a small bloat, but still I don't like to see two stupid
> > strings "pxa3xx-nand" and "pxa3xx_nand-0" bloating our kernels, so
> > that's why I chose a common macro :-)
> 
> That's fine.
> 
> > What do you think?
> 
> I'm fine with just making both use DRIVER_NAME. So I'd take this patch as-is.
> 
> One possible consequence: it makes things a little more fragile if
> people want to change one or both in the future, not noticing that
> while the driver name may (?) be changed harmlessly, it can cause
> mtdparts=... breakage.
> 

Hm.. another good point. Let me send a v3.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Sat Oct 19 09:08:47 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 19 Oct 2013 10:08:47 -0300
Subject: [PATCH] mtd: nand: use a local variable to simplify the
 nand_scan_tail
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>
References: <1382077253-21709-1-git-send-email-b32955@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>
Message-ID: <20131019130846.GB2470@localhost>

On Fri, Oct 18, 2013 at 02:11:19PM +0000, Gupta, Pekon wrote:
> > From: Huang Shijie
> > There are too many "chip->ecc" in the nand_scan_tail() which makes the
> > eyes
> > sore.
> > 
> > This patch uses a local variable "ecc" to replace the "chip->ecc" to
> > make the code more graceful.
> > 
> > Do the code change with "s/chip->ecc\./ecc->/g" in the nand_scan_tail,
> > and also change some lines by hand.
> > 
> > Signed-off-by: Huang Shijie <b32955 at freescale.com>
> > 
> Personally I won't prefer such stand-alone cleanup  _unless_ there is
> major driver re-write of the code, because this breaks the traceability
> via 'git blame'. And even in that case, this change should be applied first,
> and the other functional updates later.
> 

Hm.. I'm not sure I agree here. I like this patch and I like the effect
it has on nand_scan_tail().

On a personal note, I hardly ever use git blame at all (because it's dead
slow). Instead, I just run git log ${file} and get the latest changes on
that file.

So, for what it's worth, I think it should be merged.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Sat Oct 19 09:27:49 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 19 Oct 2013 10:27:49 -0300
Subject: [PATCH] UBIFS: remove unnecessary code in ubifs_garbage_collect
In-Reply-To: <20130917015105.GM4550@ld-irv-0074.broadcom.com>
References: <OF476A1E1E.10D82F3D-ON48257BC9.002911AE-48257BC9.002A75A8@zte.com.cn>
 <20130917015105.GM4550@ld-irv-0074.broadcom.com>
Message-ID: <20131019132748.GC2470@localhost>

(Ccing Artem who might have missed this one)

On Mon, Sep 16, 2013 at 06:51:05PM -0700, Brian Norris wrote:
> On Fri, Aug 16, 2013 at 03:43:36PM +0800, wang.bo116 at zte.com.cn wrote:
> > Hi,
> > 	In ubifs_garbage_collect,local variable "space_before" calculate twice. In fact, at the
> > beginning of the loop, there is no need to calculate this variable. Calculate it before call
> > "ubifs_garbage_collect_leb" is enough. This patch just remove the unnecessary calculate code.
> > 
> > 
> > 
> > Signed-off-by: wang bo <wang.bo116 at zte.com.cn>
> 
> Acked-by: Brian Norris <computersforpeace at gmail.com>
> 

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Sat Oct 19 09:32:06 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 19 Oct 2013 10:32:06 -0300
Subject: [PATCH v3 00/10] About the SLC/MLC
In-Reply-To: <20130827033020.GA2182@gmail.com>
References: <1377509808-29363-1-git-send-email-b32955@freescale.com>
 <20130826144153.568f2b1c@skate> <20130827033020.GA2182@gmail.com>
Message-ID: <20131019133205.GD2470@localhost>

Hi Huang,

On Mon, Aug 26, 2013 at 11:30:22PM -0400, Huang Shijie wrote:
> On Mon, Aug 26, 2013 at 02:41:53PM +0200, Thomas Petazzoni wrote:
> > 
> > On Mon, 26 Aug 2013 17:36:38 +0800, Huang Shijie wrote:
> > > In current mtd code, the MTD_NANDFLASH is used to represent both the
> > > SLC nand MLC(including the TLC). But we already have the MTD_MLCNANDFLASH
> > > to stand for the MLC. What is worse is that the JFFS2 may run on the MLC
> > > nand with current code. For the reason of READ/WRITE disturbance, the JFFS2
> > > should runs on the SLC only,
> > 
> > Pardon the probably very silly question, but would you mind giving more
> > details about why JFFS2 is not appropriate on MLC flashes? Is there
> > anything that UBI/UBIFS does that JFFS2 isn't doing to take into
> > account read/write disturbance?
> I try to explain it.
> 
> For the UBIFS, it will writes the page(including the oob) only one time;
> but for jffs2, it may writes the page(including the oob) twice, one for the
> marker, one for the real data. 
> 

It seems I overlooked this when I first read it.

Do you mean that JFFS2 will write twice: one write to the spare region,
one write in the data region, with no erase between those two?

I've looked at the JFFS2 code, but it's not trivial to follow :)
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From jason at lakedaemon.net  Sat Oct 19 10:25:49 2013
From: jason at lakedaemon.net (Jason Cooper)
Date: Sat, 19 Oct 2013 10:25:49 -0400
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <20131019063535.GC20157@1wt.eu>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131019063535.GC20157@1wt.eu>
Message-ID: <20131019142549.GO22434@titan.lakedaemon.net>

On Sat, Oct 19, 2013 at 08:35:35AM +0200, Willy Tarreau wrote:
> Hi Ezequiel,
> 
> On Fri, Oct 18, 2013 at 08:02:27PM -0300, Ezequiel Garcia wrote:
> > Hi guys,
> > 
> > This is the v2 of the work implementing NAND support in Armada 370/XP SoCs.
> > This series is probably not yet complete (see below), but I feel like
> > we're really closer now :-)
> > 
> > As in the previous version and given I don't have any public datasheet
> > to show, I'll try to write some of the most relevant parts of the controller.
> > 
> > * NFCv2 controller background
> > 
> > The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
> > larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
> > chunked transfers.
> > 
> > For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
> > we'll have this layout in the pages:
> > 
> >   ------------------------------------------------------------------------------
> >   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
> >   ------------------------------------------------------------------------------
> > 
> > The driver reads the data and spare portions independently and builds an internal
> > buffer with this layout (in the 4 KiB page case):
> > 
> >   ------------------------------------------
> >   |     4096B data     |     64B spare     |
> >   ------------------------------------------
> > 
> > Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
> > OOB, one per chunk read.
> > 
> >   -------------------------------------------------------------------
> >   |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC |
> >   -------------------------------------------------------------------
> > 
> > So, in order to achieve reading (for instance), we issue several READ0 commands
> > (with some additional controller-specific magic) and read two chunks of 2080B
> > (2048 data + 32 spare) each.
> > The driver accomodates this data to expose the NAND core a contiguous buffer
> > (4096 data + spare) or (4096 + spare + ECC + spare + ECC).
> > 
> > * ECC
> > 
> > The controller has built-in hardware ECC capabilities. In addition it is
> > configurable between two modes: 1) Hamming, 2) BCH.
> > 
> > Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
> > the controller is configured to transfer the data.
> > 
> > In the BCH mode the ECC code will be calculated for each transfered chunk
> > and expected to be located (when reading/programming) right after the spare
> > bytes as the figure above shows.
> > 
> > So, repeating the above scheme, a 2048B data chunk will be followed by 32B
> > spare, and then the ECC controller will read/write the ECC code (30B in
> > this case):
> > 
> >   ------------------------------------
> >   | 2048B data | 32B spare | 30B ECC |
> >   ------------------------------------
> > 
> > If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
> > If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
> > So in Hamming mode, a 2048B page will have a 24B ECC.
> > 
> > Despite all of the above, the controller requires the driver to only read or
> > write in multiples of 8-bytes, because the data buffer is 64-bits.
> > 
> > * Changes from v1
> > 
> > Aside from several changes based in Brian's feedback, the main changes
> > from v1 are:
> > 
> >   * The controller's clock source is now fully modeled, see patche 1 to 4.
> >     Of course, none of those patches should be taken through the mtd
> >     subsystem, but I'm adding them here for completeness.
> > 
> >   * The chip's cmdfunc() is now independently implemented in each SoC variant.
> >     The rationale behind this decision is that 'chunked' I/O is the only tested
> >     mode on the Armada370 variant, while the old 'vanilla' I/O is the only
> >     tested mode on the PXA variant.
> > 
> >     So it's safer to have an implementation for each variant.
> > 
> >   * Added support for BCH-8, in other words: 8-bits of correction in a 512-byte
> >     region. This is obtained by using a data chunk size of 1024B, thus doubling
> >     the ECC BCH strength, as per this ECC engine mechanism.
> > 
> >   * The ECC layout in use, which must be set according to the page size and
> >     desired ECC strength is now strictly chosen to match only the tested
> >     combinations.
> > 
> > * Pending stuff
> > 
> >   1. Factory bad blocks handling
> > 
> >   Currently, there's no factory bad block initial scan (when the bad block
> >   table is missing). The ECC BCH requires to layout the device's pages in
> >   a splitted "data + OOB + data + OOB" way. This layout being different from
> >   the factory layout. In other words,
> > 
> >   Factory view:
> > 
> >   -----------------------------------------------
> >   |                    Data           |x  OOB   |
> >   -----------------------------------------------
> > 
> >   Driver's view:
> > 
> >   -----------------------------------------------
> >   |      Data      | OOB |      Data   x  | OOB |
> >   -----------------------------------------------
> > 
> >   It can be seen from the above, that the factory bad block marker must be
> >   searched within the 'data' region, and not in the usual OOB region.
> > 
> >   This seems to be similar to the gpmi-nand driver, yet I really find its
> >   'bad block swapping' solution odd, so I'm trying to find something
> >   cleaner.
> > 
> >   2. ECC modeling
> > 
> >   Although I've exposed some ECC information in the ECC layout, I'm still
> >   not sure why is this needed, or if it's needed at all.
> > 
> 
> I strongly believe that all the information above is very valuable and
> that it's a shame to lose it in a cover message. It would definitely
> make sense to have this in a doc file.

Agreed.  Great work Ezequiel!  Let's capture this in Documentation/.

thx,

Jason.


From ezequiel.garcia at free-electrons.com  Sat Oct 19 12:21:59 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 19 Oct 2013 13:21:59 -0300
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <20131019142549.GO22434@titan.lakedaemon.net>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131019063535.GC20157@1wt.eu>
 <20131019142549.GO22434@titan.lakedaemon.net>
Message-ID: <20131019162158.GA3044@localhost>

On Sat, Oct 19, 2013 at 10:25:49AM -0400, Jason Cooper wrote:
> On Sat, Oct 19, 2013 at 08:35:35AM +0200, Willy Tarreau wrote:
> > Hi Ezequiel,
> > 
> > On Fri, Oct 18, 2013 at 08:02:27PM -0300, Ezequiel Garcia wrote:
> > > Hi guys,
> > > 
> > > This is the v2 of the work implementing NAND support in Armada 370/XP SoCs.
> > > This series is probably not yet complete (see below), but I feel like
> > > we're really closer now :-)
> > > 
> > > As in the previous version and given I don't have any public datasheet
> > > to show, I'll try to write some of the most relevant parts of the controller.
> > > 
> > > * NFCv2 controller background
> > > 
> > > The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
> > > larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
> > > chunked transfers.
> > > 
> > > For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
> > > we'll have this layout in the pages:
> > > 
> > >   ------------------------------------------------------------------------------
> > >   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
> > >   ------------------------------------------------------------------------------
> > > 
> > > The driver reads the data and spare portions independently and builds an internal
> > > buffer with this layout (in the 4 KiB page case):
> > > 
> > >   ------------------------------------------
> > >   |     4096B data     |     64B spare     |
> > >   ------------------------------------------
> > > 
> > > Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
> > > OOB, one per chunk read.
> > > 
> > >   -------------------------------------------------------------------
> > >   |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC |
> > >   -------------------------------------------------------------------
> > > 
> > > So, in order to achieve reading (for instance), we issue several READ0 commands
> > > (with some additional controller-specific magic) and read two chunks of 2080B
> > > (2048 data + 32 spare) each.
> > > The driver accomodates this data to expose the NAND core a contiguous buffer
> > > (4096 data + spare) or (4096 + spare + ECC + spare + ECC).
> > > 
> > > * ECC
> > > 
> > > The controller has built-in hardware ECC capabilities. In addition it is
> > > configurable between two modes: 1) Hamming, 2) BCH.
> > > 
> > > Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
> > > the controller is configured to transfer the data.
> > > 
> > > In the BCH mode the ECC code will be calculated for each transfered chunk
> > > and expected to be located (when reading/programming) right after the spare
> > > bytes as the figure above shows.
> > > 
> > > So, repeating the above scheme, a 2048B data chunk will be followed by 32B
> > > spare, and then the ECC controller will read/write the ECC code (30B in
> > > this case):
> > > 
> > >   ------------------------------------
> > >   | 2048B data | 32B spare | 30B ECC |
> > >   ------------------------------------
> > > 
> > > If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
> > > If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
> > > So in Hamming mode, a 2048B page will have a 24B ECC.
> > > 
> > > Despite all of the above, the controller requires the driver to only read or
> > > write in multiples of 8-bytes, because the data buffer is 64-bits.
> > > 
> > > * Changes from v1
> > > 
> > > Aside from several changes based in Brian's feedback, the main changes
> > > from v1 are:
> > > 
> > >   * The controller's clock source is now fully modeled, see patche 1 to 4.
> > >     Of course, none of those patches should be taken through the mtd
> > >     subsystem, but I'm adding them here for completeness.
> > > 
> > >   * The chip's cmdfunc() is now independently implemented in each SoC variant.
> > >     The rationale behind this decision is that 'chunked' I/O is the only tested
> > >     mode on the Armada370 variant, while the old 'vanilla' I/O is the only
> > >     tested mode on the PXA variant.
> > > 
> > >     So it's safer to have an implementation for each variant.
> > > 
> > >   * Added support for BCH-8, in other words: 8-bits of correction in a 512-byte
> > >     region. This is obtained by using a data chunk size of 1024B, thus doubling
> > >     the ECC BCH strength, as per this ECC engine mechanism.
> > > 
> > >   * The ECC layout in use, which must be set according to the page size and
> > >     desired ECC strength is now strictly chosen to match only the tested
> > >     combinations.
> > > 
> > > * Pending stuff
> > > 
> > >   1. Factory bad blocks handling
> > > 
> > >   Currently, there's no factory bad block initial scan (when the bad block
> > >   table is missing). The ECC BCH requires to layout the device's pages in
> > >   a splitted "data + OOB + data + OOB" way. This layout being different from
> > >   the factory layout. In other words,
> > > 
> > >   Factory view:
> > > 
> > >   -----------------------------------------------
> > >   |                    Data           |x  OOB   |
> > >   -----------------------------------------------
> > > 
> > >   Driver's view:
> > > 
> > >   -----------------------------------------------
> > >   |      Data      | OOB |      Data   x  | OOB |
> > >   -----------------------------------------------
> > > 
> > >   It can be seen from the above, that the factory bad block marker must be
> > >   searched within the 'data' region, and not in the usual OOB region.
> > > 
> > >   This seems to be similar to the gpmi-nand driver, yet I really find its
> > >   'bad block swapping' solution odd, so I'm trying to find something
> > >   cleaner.
> > > 
> > >   2. ECC modeling
> > > 
> > >   Although I've exposed some ECC information in the ECC layout, I'm still
> > >   not sure why is this needed, or if it's needed at all.
> > > 
> > 
> > I strongly believe that all the information above is very valuable and
> > that it's a shame to lose it in a cover message. It would definitely
> > make sense to have this in a doc file.
> 
> Agreed.  Great work Ezequiel!  Let's capture this in Documentation/.
> 

Wait a second!

  $ ls Documentation/mtd/ | wc -l
  1

Isn't documenting deprecated? ...

Just kiddin'! I'll add this and the other cover to Documentation/
so typos and english fixes are welcome!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Sat Oct 19 17:19:25 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sat, 19 Oct 2013 18:19:25 -0300
Subject: [PATCH v3] mtd: nand: pxa3xx: Fix registered MTD name
Message-ID: <1382217565-11312-1-git-send-email-ezequiel.garcia@free-electrons.com>

In a recent commit:

  commit f455578dd961087a5cf94730d9f6489bb1d355f0
  Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
  Date:   Mon Aug 12 14:14:53 2013 -0300

  mtd: nand: pxa3xx: Remove hardcoded mtd name

  There's no advantage in using a hardcoded name for the mtd device.
  Instead use the provided by the platform_device.

The MTD name was changed to use the one provided by the platform_device.
However, this can be problematic as some users want to set partitions
using the kernel parameter 'mtdparts', where the name is needed.

Therefore, to avoid regressions in users relying in 'mtdparts' we revert
the change and use the previous one 'pxa3xx_nand-0'.

While at it, let's put a big comment and prevent this change from happening
ever again.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
v2->v3:
  * Limit the name change to mtd->name. This means that driver's name
    and the mtd->name will be different. We do this because:
    1. We want to read a simpler 'pxa3xx-nand' driver name in
       kernel messages and other kernel reports.
    2. We're forced to use the silly name 'pxa3xx_nand-0' for backwards
       compatibility.

v1->v2:
  * Use exactly the same name as before, and avoid regressions
    instead of using any seemingly better or cleaner one.

 drivers/mtd/nand/pxa3xx_nand.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index cbc7240..bae1573 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1749,7 +1749,12 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
 	for (cs = 0; cs < pdata->num_cs; cs++) {
 		struct mtd_info *mtd = info->host[cs]->mtd;
 
-		mtd->name = pdev->name;
+		/*
+		 * The mtd name matches the one used in 'mtdparts' kernel
+		 * parameter. This name cannot be changed or otherwise
+		 * user's mtd partitions configuration would get broken.
+		 */
+		mtd->name = "pxa3xx_nand-0";
 		info->cs = cs;
 		ret = pxa3xx_nand_scan(mtd);
 		if (ret) {
-- 
1.8.1.5



From pekon at ti.com  Sun Oct 20 03:01:11 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Sun, 20 Oct 2013 07:01:11 +0000
Subject: [PATCH] mtd: nand: use a local variable to simplify the
 nand_scan_tail
In-Reply-To: <20131019130846.GB2470@localhost>
References: <1382077253-21709-1-git-send-email-b32955@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>
 <20131019130846.GB2470@localhost>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA28EB9@DBDE04.ent.ti.com>

> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> > On Fri, Oct 18, 2013 at 02:11:19PM +0000, Gupta, Pekon wrote:
> > > From: Huang Shijie
> > > There are too many "chip->ecc" in the nand_scan_tail() which makes the
> > > eyes
> > > sore.
> > >
> > > This patch uses a local variable "ecc" to replace the "chip->ecc" to
> > > make the code more graceful.
> > >
> > > Do the code change with "s/chip->ecc\./ecc->/g" in the nand_scan_tail,
> > > and also change some lines by hand.
> > >
> > > Signed-off-by: Huang Shijie <b32955 at freescale.com>
> > >
> > Personally I won't prefer such stand-alone cleanup  _unless_ there is
> > major driver re-write of the code, because this breaks the traceability
> > via 'git blame'. And even in that case, this change should be applied first,
> > and the other functional updates later.
> >
> 
> Hm.. I'm not sure I agree here. I like this patch and I like the effect
> it has on nand_scan_tail().
> 
> On a personal note, I hardly ever use git blame at all (because it's dead
> slow). Instead, I just run git log ${file} and get the latest changes on
> that file.
> 
Its rather difficult to use 'git log' especially when you are tracing or debugging
a generic driver, and want to know why this piece of code was introduced,
and the idea behind it. 'git log' won?t show line by line commit details.

So, I'm not against this clean-up, just that please schedule this patch
*before some major re-write of nand_scan_tail()*, so that the 'git blame'
is preserved for the new changes after this cleanup.
I remember there is another major patch from Shijie for renaming
chip->ecc.size and adding them as sysfs entry. Good to merge all such
renaming patches in one-go.


With regards, pekon

From ezequiel.garcia at free-electrons.com  Sun Oct 20 06:54:00 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 20 Oct 2013 07:54:00 -0300
Subject: [PATCH] mtd: nand: use a local variable to simplify the
 nand_scan_tail
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA28EB9@DBDE04.ent.ti.com>
References: <1382077253-21709-1-git-send-email-b32955@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>
 <20131019130846.GB2470@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA28EB9@DBDE04.ent.ti.com>
Message-ID: <20131020105359.GA2465@localhost>

On Sun, Oct 20, 2013 at 07:01:11AM +0000, Gupta, Pekon wrote:
> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> > > On Fri, Oct 18, 2013 at 02:11:19PM +0000, Gupta, Pekon wrote:
> > > > From: Huang Shijie
> > > > There are too many "chip->ecc" in the nand_scan_tail() which makes the
> > > > eyes
> > > > sore.
> > > >
> > > > This patch uses a local variable "ecc" to replace the "chip->ecc" to
> > > > make the code more graceful.
> > > >
> > > > Do the code change with "s/chip->ecc\./ecc->/g" in the nand_scan_tail,
> > > > and also change some lines by hand.
> > > >
> > > > Signed-off-by: Huang Shijie <b32955 at freescale.com>
> > > >
> > > Personally I won't prefer such stand-alone cleanup  _unless_ there is
> > > major driver re-write of the code, because this breaks the traceability
> > > via 'git blame'. And even in that case, this change should be applied first,
> > > and the other functional updates later.
> > >
> > 
> > Hm.. I'm not sure I agree here. I like this patch and I like the effect
> > it has on nand_scan_tail().
> > 
> > On a personal note, I hardly ever use git blame at all (because it's dead
> > slow). Instead, I just run git log ${file} and get the latest changes on
> > that file.
> > 
> Its rather difficult to use 'git log' especially when you are tracing or debugging
> a generic driver, and want to know why this piece of code was introduced,
> and the idea behind it. 'git log' won?t show line by line commit details.
> 

Quite the opposite 'git log --patch' shows the commit details.
Or maybe you need something that I'm not aware of?

I really don't think we should dis-encourage cleanups -in what ever form
and time they might come- just to preserve the last 'major' author of a file.

But this is just my two cents...
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Sun Oct 20 08:06:05 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 20 Oct 2013 09:06:05 -0300
Subject: [PATCH] mtd: cmdlinepart: use cmdline partition parser lib
In-Reply-To: <C3050A4DBA34F345975765E43127F10F1C0643B8@szxeml512-mbx.china.huawei.com>
References: <C3050A4DBA34F345975765E43127F10F1C0643B8@szxeml512-mbx.china.huawei.com>
Message-ID: <20131020120603.GA18678@localhost>

Hi Cai,

Sorry for the late review. See below some minor comments.

On Thu, Aug 15, 2013 at 11:19:36AM +0000, Caizhiyong wrote:
> From: Cai Zhiyong <caizhiyong at huawei.com>
> 
> MTD cmdline partition use cmdline partition parser lib
> 
> reference: https://lkml.org/lkml/2013/8/6/550
> 

How about some more verbose commit message explaining the impact
of this change, or clearly stating there's no functionality change
(as it should given the mtdparts parameter _must_ be kept compatible).

> Signed-off-by: Cai ZhiYong <caizhiyong at huawei.com>
> ---
>  Documentation/block/cmdline-partition.txt |  93 +++++---
>  block/cmdline-parser.c                    |  16 +-
>  drivers/mtd/Kconfig                       |   1 +
>  drivers/mtd/cmdlinepart.c                 | 361 ++++--------------------------
>  include/linux/cmdline-parser.h            |   8 +-
>  5 files changed, 111 insertions(+), 368 deletions(-)
> 

This a nice diffstat, nice job!

> diff --git a/Documentation/block/cmdline-partition.txt b/Documentation/block/cmdline-partition.txt
> index 651863d..adc5f7a 100644
> --- a/Documentation/block/cmdline-partition.txt
> +++ b/Documentation/block/cmdline-partition.txt
> @@ -1,40 +1,59 @@
>  Embedded device command line partition
> -=====================================================================
> -
> -Read block device partition table from command line.
> -The partition used for fixed block device (eMMC) embedded device.
> -It is no MBR, save storage space. Bootloader can be easily accessed
> -by absolute address of data on the block device.
> -Users can easily change the partition.
> -
> -The format for the command line is just like mtdparts:
> -
> -blkdevparts=<blkdev-def>[;<blkdev-def>]
> +Authors: Cai Zhiyong <caizhiyong at huawei.com>
> +
> +The format for the command line is as follows,
> +it is used by MTD device (reference drivers/mtd/cmdlinepart.c) and
> +block device (reference block/partitions/cmdline.c)
> +
> +================================================================================
> +For MTD device:
> +  mtdparts=<mtddef>[;<mtddef]
> +  <mtddef>  := <mtd-id>:<partdef>[,<partdef>]
> +  <partdef> := <size>[@<offset>][<name>][ro][lk]
> +  <mtd-id>  := unique name used in mapping driver/device (mtd->name)
> +  <size>    := standard linux memsize OR "-" to denote all remaining space
> +               size is automatically truncated at end of device
> +               if specified or trucated size is 0 the part is skipped
> +  <offset>  := standard linux memsize
> +               if omitted the part will immediately follow the previous part
> +               or 0 if the first part
> +  <name>    := '(' NAME ')'
> +               NAME will appear in /proc/mtd
> +
> +  <size> and <offset> can be specified such that the parts are out of order
> +  in physical memory and may even overlap.
> +
> +  The parts are assigned MTD numbers in the order they are specified in the
> +  command line regardless of their order in physical memory.
> +
> +  Examples:
> +
> +  1 NOR Flash, with 1 single writable partition:
> +  edb7312-nor:-
> +
> +  1 NOR Flash with 2 partitions, 1 NAND with one
> +  edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
> +
> +================================================================================
> +For block device:
> +  blkdevparts=<blkdev-def>[;<blkdev-def>]
>    <blkdev-def> := <blkdev-id>:<partdef>[,<partdef>]
> -    <partdef> := <size>[@<offset>](part-name)
> -
> -<blkdev-id>
> -    block device disk name, embedded device used fixed block device,
> -    it's disk name also fixed. such as: mmcblk0, mmcblk1, mmcblk0boot0.
> -
> -<size>
> -    partition size, in bytes, such as: 512, 1m, 1G.
> -
> -<offset>
> -    partition start address, in bytes.
> -
> -(part-name)
> -    partition name, kernel send uevent with "PARTNAME". application can create
> -    a link to block device partition with the name "PARTNAME".
> -    user space application can access partition by partition name.
> -
> -Example:
> -    eMMC disk name is "mmcblk0" and "mmcblk0boot0"
> -
> -  bootargs:
> +  <partdef> := <size>[@<offset>][<name>]
> +  <blkdev-id>
> +       block device disk name, embedded device used fixed block device,
> +       it's disk name also fixed. such as: mmcblk0, mmcblk1, mmcblk0boot0.
> +  <size>    := standard linux memsize OR "-" to denote all remaining space
> +               size is automatically truncated at end of device
> +               if specified or trucated size is 0 the part is skipped
> +  <offset>  := standard linux memsize
> +               if omitted the part will immediately follow the previous part
> +               or 0 if the first part
> +  <name>    := '(' NAME ')'
> +        partition name, kernel send uevent with "PARTNAME". application could
> +        create a link to block device partition with the name "PARTNAME".
> +        user space application can access partition by partition name.
> +
> +  Example:
> +
> +    eMMC disk name is "mmcblk0" and "mmcblk0boot0", bootargs:
>      'blkdevparts=mmcblk0:1G(data0),1G(data1),-;mmcblk0boot0:1m(boot),-(kernel)'
> -
> -  dmesg:
> -    mmcblk0: p1(data0) p2(data1) p3()
> -    mmcblk0boot0: p1(boot) p2(kernel)
> -
> diff --git a/block/cmdline-parser.c b/block/cmdline-parser.c
> index 18fb435..8c09db3 100644
> --- a/block/cmdline-parser.c
> +++ b/block/cmdline-parser.c
> @@ -4,8 +4,6 @@
>   * Written by Cai Zhiyong <caizhiyong at huawei.com>
>   *
>   */
> -#include <linux/buffer_head.h>
> -#include <linux/module.h>

Hm.. this header removal seems an unrelated change, right?
I'd suggest to send a separate patch for this.

>  #include <linux/cmdline-parser.h>
>  
>  static int parse_subpart(struct cmdline_subpart **subpart, char *partdef)
> @@ -158,6 +156,7 @@ void cmdline_parts_free(struct cmdline_parts **parts)
>  		*parts = next_parts;
>  	}
>  }
> +EXPORT_SYMBOL(cmdline_parts_free);
>  
>  int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline)
>  {
> @@ -205,6 +204,7 @@ fail:
>  	cmdline_parts_free(parts);
>  	goto done;
>  }
> +EXPORT_SYMBOL(cmdline_parts_parse);
>  
>  struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
>  					 const char *bdev)
> @@ -213,16 +213,17 @@ struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
>  		parts = parts->next_parts;
>  	return parts;
>  }
> +EXPORT_SYMBOL(cmdline_parts_find);
>  
>  /*
>   *  add_part()
>   *    0 success.
>   *    1 can not add so many partitions.
>   */
> -void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
> -		       int slot,
> -		       int (*add_part)(int, struct cmdline_subpart *, void *),
> -		       void *param)
> +int cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
> +		      int slot,
> +		      int (*add_part)(int, struct cmdline_subpart *, void *),
> +		      void *param)
>  
>  {
>  	sector_t from = 0;
> @@ -246,4 +247,7 @@ void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
>  		if (add_part(slot, subpart, param))
>  			break;
>  	}
> +
> +	return slot;
>  }
> +EXPORT_SYMBOL(cmdline_parts_set);
> diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
> index 5fab4e6e..6f7f9ca 100644
> --- a/drivers/mtd/Kconfig
> +++ b/drivers/mtd/Kconfig
> @@ -75,6 +75,7 @@ endif # MTD_REDBOOT_PARTS
>  
>  config MTD_CMDLINE_PARTS
>  	tristate "Command line partition table parsing"
> +	select CMDLINE_PARSER
>  	depends on MTD
>  	---help---
>  	  Allow generic configuration of the MTD partition tables via the kernel
> diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
> index 721caeb..79bd584 100644
> --- a/drivers/mtd/cmdlinepart.c
> +++ b/drivers/mtd/cmdlinepart.c
> @@ -18,34 +18,8 @@
>   * along with this program; if not, write to the Free Software
>   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
>   *
> - * The format for the command line is as follows:
> + * Verbose please reference "Documentation/block/cmdline-partition.txt"
>   *
> - * mtdparts=<mtddef>[;<mtddef]
> - * <mtddef>  := <mtd-id>:<partdef>[,<partdef>]
> - * <partdef> := <size>[@<offset>][<name>][ro][lk]
> - * <mtd-id>  := unique name used in mapping driver/device (mtd->name)
> - * <size>    := standard linux memsize OR "-" to denote all remaining space
> - *              size is automatically truncated at end of device
> - *              if specified or trucated size is 0 the part is skipped
> - * <offset>  := standard linux memsize
> - *              if omitted the part will immediately follow the previous part
> - *              or 0 if the first part
> - * <name>    := '(' NAME ')'
> - *              NAME will appear in /proc/mtd
> - *
> - * <size> and <offset> can be specified such that the parts are out of order
> - * in physical memory and may even overlap.
> - *
> - * The parts are assigned MTD numbers in the order they are specified in the
> - * command line regardless of their order in physical memory.
> - *
> - * Examples:
> - *
> - * 1 NOR Flash, with 1 single writable partition:
> - * edb7312-nor:-
> - *
> - * 1 NOR Flash with 2 partitions, 1 NAND with one
> - * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
>   */
>  
>  #include <linux/kernel.h>
> @@ -54,249 +28,43 @@
>  #include <linux/mtd/partitions.h>
>  #include <linux/module.h>
>  #include <linux/err.h>
> +#include <linux/cmdline-parser.h>
>  
> -/* error message prefix */
> -#define ERRP "mtd: "
> -
> -/* debug macro */
> -#if 0
> -#define dbg(x) do { printk("DEBUG-CMDLINE-PART: "); printk x; } while(0)
> -#else
> -#define dbg(x)
> -#endif
> -
> -
> -/* special size referring to all the remaining space in a partition */
> -#define SIZE_REMAINING ULLONG_MAX
> -#define OFFSET_CONTINUOUS ULLONG_MAX
> -
> -struct cmdline_mtd_partition {
> -	struct cmdline_mtd_partition *next;
> -	char *mtd_id;
> -	int num_parts;
> -	struct mtd_partition *parts;
> -};
> -
> -/* mtdpart_setup() parses into here */
> -static struct cmdline_mtd_partition *partitions;
> -
> -/* the command line passed to mtdpart_setup() */
>  static char *mtdparts;
> -static char *cmdline;
> -static int cmdline_parsed;
> +static struct cmdline_parts *mtd_cmdline_parts;
>  
> -/*
> - * Parse one partition definition for an MTD. Since there can be many
> - * comma separated partition definitions, this function calls itself
> - * recursively until no more partition definitions are found. Nice side
> - * effect: the memory to keep the mtd_partition structs and the names
> - * is allocated upon the last definition being found. At that point the
> - * syntax has been verified ok.
> - */
> -static struct mtd_partition * newpart(char *s,
> -				      char **retptr,
> -				      int *num_parts,
> -				      int this_part,
> -				      unsigned char **extra_mem_ptr,
> -				      int extra_mem_size)
> +static int add_part(int slot, struct cmdline_subpart *subpart, void *param)
>  {
> -	struct mtd_partition *parts;
> -	unsigned long long size, offset = OFFSET_CONTINUOUS;
> -	char *name;
> -	int name_len;
> -	unsigned char *extra_mem;
> -	char delim;
> -	unsigned int mask_flags;
> -
> -	/* fetch the partition size */
> -	if (*s == '-') {
> -		/* assign all remaining space to this partition */
> -		size = SIZE_REMAINING;
> -		s++;
> -	} else {
> -		size = memparse(s, &s);
> -		if (size < PAGE_SIZE) {
> -			printk(KERN_ERR ERRP "partition size too small (%llx)\n",
> -			       size);
> -			return ERR_PTR(-EINVAL);
> -		}
> -	}
> +	struct mtd_partition *mtdpart = &((struct mtd_partition *)param)[slot];
>  
> -	/* fetch partition name and flags */
> -	mask_flags = 0; /* this is going to be a regular partition */
> -	delim = 0;
> +	mtdpart->offset = subpart->from;
> +	mtdpart->size = subpart->size;
> +	mtdpart->name = subpart->name;
> +	mtdpart->mask_flags = 0;
>  
> -	/* check for offset */
> -	if (*s == '@') {
> -		s++;
> -		offset = memparse(s, &s);
> -	}
> -
> -	/* now look for name */
> -	if (*s == '(')
> -		delim = ')';
> -
> -	if (delim) {
> -		char *p;
> -
> -		name = ++s;
> -		p = strchr(name, delim);
> -		if (!p) {
> -			printk(KERN_ERR ERRP "no closing %c found in partition name\n", delim);
> -			return ERR_PTR(-EINVAL);
> -		}
> -		name_len = p - name;
> -		s = p + 1;
> -	} else {
> -		name = NULL;
> -		name_len = 13; /* Partition_000 */
> -	}
> -
> -	/* record name length for memory allocation later */
> -	extra_mem_size += name_len + 1;
> -
> -	/* test for options */
> -	if (strncmp(s, "ro", 2) == 0) {
> -		mask_flags |= MTD_WRITEABLE;
> -		s += 2;
> -	}
> +	if (subpart->flags & PF_RDONLY)
> +		mtdpart->mask_flags |= MTD_WRITEABLE;
>  
>  	/* if lk is found do NOT unlock the MTD partition*/
> -	if (strncmp(s, "lk", 2) == 0) {
> -		mask_flags |= MTD_POWERUP_LOCK;
> -		s += 2;
> -	}
> -
> -	/* test if more partitions are following */
> -	if (*s == ',') {
> -		if (size == SIZE_REMAINING) {
> -			printk(KERN_ERR ERRP "no partitions allowed after a fill-up partition\n");
> -			return ERR_PTR(-EINVAL);
> -		}
> -		/* more partitions follow, parse them */
> -		parts = newpart(s + 1, &s, num_parts, this_part + 1,
> -				&extra_mem, extra_mem_size);
> -		if (IS_ERR(parts))
> -			return parts;
> -	} else {
> -		/* this is the last partition: allocate space for all */
> -		int alloc_size;
> -
> -		*num_parts = this_part + 1;
> -		alloc_size = *num_parts * sizeof(struct mtd_partition) +
> -			     extra_mem_size;
> -
> -		parts = kzalloc(alloc_size, GFP_KERNEL);
> -		if (!parts)
> -			return ERR_PTR(-ENOMEM);
> -		extra_mem = (unsigned char *)(parts + *num_parts);
> -	}
> -
> -	/* enter this partition (offset will be calculated later if it is zero at this point) */
> -	parts[this_part].size = size;
> -	parts[this_part].offset = offset;
> -	parts[this_part].mask_flags = mask_flags;
> -	if (name)
> -		strlcpy(extra_mem, name, name_len + 1);
> -	else
> -		sprintf(extra_mem, "Partition_%03d", this_part);
> -	parts[this_part].name = extra_mem;
> -	extra_mem += name_len + 1;
> -
> -	dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n",
> -	     this_part, parts[this_part].name, parts[this_part].offset,
> -	     parts[this_part].size, parts[this_part].mask_flags));
> +	if (subpart->flags & PF_POWERUP_LOCK)
> +		mtdpart->mask_flags |= MTD_POWERUP_LOCK;
>  
> -	/* return (updated) pointer to extra_mem memory */
> -	if (extra_mem_ptr)
> -		*extra_mem_ptr = extra_mem;
> -
> -	/* return (updated) pointer command line string */
> -	*retptr = s;
> -
> -	/* return partition table */
> -	return parts;
> +	return 0;
>  }
>  
>  /*
> - * Parse the command line.
> + * This is the handler for our kernel parameter, called from
> + * main.c::checksetup(). Note that we can not yet kmalloc() anything,
> + * so we only save the commandline for later processing.
> + *
> + * This function needs to be visible for bootloaders.
>   */
> -static int mtdpart_setup_real(char *s)
> +static int __init mtdpart_setup(char *s)
>  {
> -	cmdline_parsed = 1;
> -
> -	for( ; s != NULL; )
> -	{
> -		struct cmdline_mtd_partition *this_mtd;
> -		struct mtd_partition *parts;
> -		int mtd_id_len, num_parts;
> -		char *p, *mtd_id;
> -
> -		mtd_id = s;
> -
> -		/* fetch <mtd-id> */
> -		p = strchr(s, ':');
> -		if (!p) {
> -			printk(KERN_ERR ERRP "no mtd-id\n");
> -			return -EINVAL;
> -		}
> -		mtd_id_len = p - mtd_id;
> -
> -		dbg(("parsing <%s>\n", p+1));
> -
> -		/*
> -		 * parse one mtd. have it reserve memory for the
> -		 * struct cmdline_mtd_partition and the mtd-id string.
> -		 */
> -		parts = newpart(p + 1,		/* cmdline */
> -				&s,		/* out: updated cmdline ptr */
> -				&num_parts,	/* out: number of parts */
> -				0,		/* first partition */
> -				(unsigned char**)&this_mtd, /* out: extra mem */
> -				mtd_id_len + 1 + sizeof(*this_mtd) +
> -				sizeof(void*)-1 /*alignment*/);
> -		if (IS_ERR(parts)) {
> -			/*
> -			 * An error occurred. We're either:
> -			 * a) out of memory, or
> -			 * b) in the middle of the partition spec
> -			 * Either way, this mtd is hosed and we're
> -			 * unlikely to succeed in parsing any more
> -			 */
> -			 return PTR_ERR(parts);
> -		 }
> -
> -		/* align this_mtd */
> -		this_mtd = (struct cmdline_mtd_partition *)
> -				ALIGN((unsigned long)this_mtd, sizeof(void *));
> -		/* enter results */
> -		this_mtd->parts = parts;
> -		this_mtd->num_parts = num_parts;
> -		this_mtd->mtd_id = (char*)(this_mtd + 1);
> -		strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
> -
> -		/* link into chain */
> -		this_mtd->next = partitions;
> -		partitions = this_mtd;
> -
> -		dbg(("mtdid=<%s> num_parts=<%d>\n",
> -		     this_mtd->mtd_id, this_mtd->num_parts));
> -
> -
> -		/* EOS - we're done */
> -		if (*s == 0)
> -			break;
> -
> -		/* does another spec follow? */
> -		if (*s != ';') {
> -			printk(KERN_ERR ERRP "bad character after partition (%c)\n", *s);
> -			return -EINVAL;
> -		}
> -		s++;
> -	}
> -
> -	return 0;
> +	mtdparts = s;
> +	return 1;
>  }
> +__setup("mtdparts=", mtdpart_setup);
>  
>  /*
>   * Main function to be called from the MTD mapping driver/device to
> @@ -309,82 +77,35 @@ static int parse_cmdline_partitions(struct mtd_info *master,
>  				    struct mtd_partition **pparts,
>  				    struct mtd_part_parser_data *data)
>  {
> -	unsigned long long offset;
> -	int i, err;
> -	struct cmdline_mtd_partition *part;
> -	const char *mtd_id = master->name;
> +	struct cmdline_parts *parts;
>  
> -	/* parse command line */
> -	if (!cmdline_parsed) {
> -		err = mtdpart_setup_real(cmdline);
> -		if (err)
> -			return err;
> -	}
> +	if (mtdparts) {
> +		if (mtd_cmdline_parts)
> +			cmdline_parts_free(&mtd_cmdline_parts);
> +
> +		if (cmdline_parts_parse(&mtd_cmdline_parts, mtdparts)) {
> +			mtdparts = NULL;
> +			return -EINVAL;
> +		}
>  
> -	/*
> -	 * Search for the partition definition matching master->name.
> -	 * If master->name is not set, stop at first partition definition.
> -	 */
> -	for (part = partitions; part; part = part->next) {
> -		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))
> -			break;
> +		mtdparts = NULL;
>  	}
>  
> -	if (!part)
> +	if (!mtd_cmdline_parts)
>  		return 0;
>  
> -	for (i = 0, offset = 0; i < part->num_parts; i++) {
> -		if (part->parts[i].offset == OFFSET_CONTINUOUS)
> -			part->parts[i].offset = offset;
> -		else
> -			offset = part->parts[i].offset;
> -
> -		if (part->parts[i].size == SIZE_REMAINING)
> -			part->parts[i].size = master->size - offset;
> -
> -		if (offset + part->parts[i].size > master->size) {
> -			printk(KERN_WARNING ERRP
> -			       "%s: partitioning exceeds flash size, truncating\n",
> -			       part->mtd_id);
> -			part->parts[i].size = master->size - offset;
> -		}
> -		offset += part->parts[i].size;
> -
> -		if (part->parts[i].size == 0) {
> -			printk(KERN_WARNING ERRP
> -			       "%s: skipping zero sized partition\n",
> -			       part->mtd_id);
> -			part->num_parts--;
> -			memmove(&part->parts[i], &part->parts[i + 1],
> -				sizeof(*part->parts) * (part->num_parts - i));
> -			i--;
> -		}
> -	}
> +	parts = cmdline_parts_find(mtd_cmdline_parts, master->name);
> +	if (!parts)
> +		return 0;
>  
> -	*pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
> -			  GFP_KERNEL);
> +	*pparts = kzalloc(sizeof(**pparts) * parts->nr_subparts, GFP_KERNEL);
>  	if (!*pparts)
>  		return -ENOMEM;
>  
> -	return part->num_parts;
> -}
> -
> -
> -/*
> - * This is the handler for our kernel parameter, called from
> - * main.c::checksetup(). Note that we can not yet kmalloc() anything,
> - * so we only save the commandline for later processing.
> - *
> - * This function needs to be visible for bootloaders.
> - */
> -static int __init mtdpart_setup(char *s)
> -{
> -	cmdline = s;
> -	return 1;
> +	return cmdline_parts_set(parts, master->size, 0, add_part,
> +				 (void *)*pparts);
>  }
>  
> -__setup("mtdparts=", mtdpart_setup);
> -
>  static struct mtd_part_parser cmdline_parser = {
>  	.owner = THIS_MODULE,
>  	.parse_fn = parse_cmdline_partitions,
> @@ -393,8 +114,6 @@ static struct mtd_part_parser cmdline_parser = {
>  
>  static int __init cmdline_parser_init(void)
>  {
> -	if (mtdparts)
> -		mtdpart_setup(mtdparts);
>  	return register_mtd_parser(&cmdline_parser);
>  }
>  
> diff --git a/include/linux/cmdline-parser.h b/include/linux/cmdline-parser.h
> index 98e892e..43b65a9 100644
> --- a/include/linux/cmdline-parser.h
> +++ b/include/linux/cmdline-parser.h
> @@ -35,9 +35,9 @@ int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline);
>  struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
>  					 const char *bdev);
>  
> -void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
> -		       int slot,
> -		       int (*add_part)(int, struct cmdline_subpart *, void *),
> -		       void *param);
> +int cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
> +		      int slot,
> +		      int (*add_part)(int, struct cmdline_subpart *, void *),
> +		      void *param);
>  
>  #endif /* CMDLINEPARSEH */
> -- 
> 1.8.1.5
> 

I'd like to review the patch in detail and test it, but being a bit old,
the patch doesn't apply as it is on v3.12-rc5. Care to resend an update?

Brian: I saw you want to move forward with this. I guess we can give
it a test, and if all the possible 'mtdparts' use cases work, then
we shouldn't object the cleanup, right?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From thomas.petazzoni at free-electrons.com  Sun Oct 20 13:50:49 2013
From: thomas.petazzoni at free-electrons.com (Thomas Petazzoni)
Date: Sun, 20 Oct 2013 19:50:49 +0200
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <20131019162158.GA3044@localhost>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131019063535.GC20157@1wt.eu>
 <20131019142549.GO22434@titan.lakedaemon.net>
 <20131019162158.GA3044@localhost>
Message-ID: <20131020195049.7e683d0f@skate>

Dear Ezequiel Garcia,

On Sat, 19 Oct 2013 13:21:59 -0300, Ezequiel Garcia wrote:

> > > I strongly believe that all the information above is very valuable and
> > > that it's a shame to lose it in a cover message. It would definitely
> > > make sense to have this in a doc file.
> > 
> > Agreed.  Great work Ezequiel!  Let's capture this in Documentation/.
> > 
> 
> Wait a second!
> 
>   $ ls Documentation/mtd/ | wc -l
>   1
> 
> Isn't documenting deprecated? ...
> 
> Just kiddin'! I'll add this and the other cover to Documentation/
> so typos and english fixes are welcome!

I certainly agree this documentation should be kept, but I'm wondering
if keeping it as a comment inside the driver doesn't make more sense.
This document is really more about specific implementation details, and
the next person looking at the driver is not very likely to search such
details in Documentation/, in my opinion.

Best regards,

Thomas
-- 
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com


From jason at lakedaemon.net  Sun Oct 20 15:24:41 2013
From: jason at lakedaemon.net (Jason Cooper)
Date: Sun, 20 Oct 2013 15:24:41 -0400
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <20131020195049.7e683d0f@skate>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131019063535.GC20157@1wt.eu>
 <20131019142549.GO22434@titan.lakedaemon.net>
 <20131019162158.GA3044@localhost> <20131020195049.7e683d0f@skate>
Message-ID: <20131020192441.GC15169@titan.lakedaemon.net>

On Sun, Oct 20, 2013 at 07:50:49PM +0200, Thomas Petazzoni wrote:
> Dear Ezequiel Garcia,
> 
> On Sat, 19 Oct 2013 13:21:59 -0300, Ezequiel Garcia wrote:
> 
> > > > I strongly believe that all the information above is very valuable and
> > > > that it's a shame to lose it in a cover message. It would definitely
> > > > make sense to have this in a doc file.
> > > 
> > > Agreed.  Great work Ezequiel!  Let's capture this in Documentation/.
> > > 
> > 
> > Wait a second!
> > 
> >   $ ls Documentation/mtd/ | wc -l
> >   1
> > 
> > Isn't documenting deprecated? ...
> > 
> > Just kiddin'! I'll add this and the other cover to Documentation/
> > so typos and english fixes are welcome!
> 
> I certainly agree this documentation should be kept, but I'm wondering
> if keeping it as a comment inside the driver doesn't make more sense.

That's a _long_ comment...

> This document is really more about specific implementation details, and
> the next person looking at the driver is not very likely to search such
> details in Documentation/, in my opinion.

A succinct comment in the code pointing to the Documentation/ should be
sufficient.

thx,

Jason.


From b32955 at freescale.com  Sun Oct 20 22:58:31 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 21 Oct 2013 10:58:31 +0800
Subject: [PATCH v3 00/10] About the SLC/MLC
In-Reply-To: <20131019133205.GD2470@localhost>
References: <1377509808-29363-1-git-send-email-b32955@freescale.com>
 <20130826144153.568f2b1c@skate> <20130827033020.GA2182@gmail.com>
 <20131019133205.GD2470@localhost>
Message-ID: <52649857.2040306@freescale.com>

? 2013?10?19? 21:32, Ezequiel Garcia ??:
> Do you mean that JFFS2 will write twice: one write to the spare region,
> one write in the data region, with no erase between those two?
yes. The first time to write the clean marker, the another is to write 
the data.

thanks
Huang Shijie



From b32955 at freescale.com  Sun Oct 20 23:02:26 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 21 Oct 2013 11:02:26 +0800
Subject: [PATCH] mtd: nand: use a local variable to simplify the
 nand_scan_tail
In-Reply-To: <20131020105359.GA2465@localhost>
References: <1382077253-21709-1-git-send-email-b32955@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>
 <20131019130846.GB2470@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA28EB9@DBDE04.ent.ti.com>
 <20131020105359.GA2465@localhost>
Message-ID: <52649942.40607@freescale.com>

? 2013?10?20? 18:54, Ezequiel Garcia ??:
> Quite the opposite 'git log --patch' shows the commit details.
> Or maybe you need something that I'm not aware of?
>
I also think the git-log is better then git-blame. :)




thanks
Huang Shijie



From b32955 at freescale.com  Sun Oct 20 23:30:34 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 21 Oct 2013 11:30:34 +0800
Subject: gpmi-mtd ecc regression
In-Reply-To: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
References: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
Message-ID: <52649FDA.1030804@freescale.com>

? 2013?10?19? 01:03, Tim Harvey ??:
> Huang,
>
> The patch you made to obtain ECC info from the chip
> (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/mtd/nand/gpmi-nand?id=2febcdf84b75aae627c61f0a5bf531a69299966c)
> has caused a regression for an i.MX6 board I'm working with that uses
> NAND and ubifs.
>
> I'm using a Micron MT29F8G08
> (http://download.micron.com/pdf/datasheets/flash/nand/2_4_8gb_nand_m49a.pdf)
> which has:
> page size: 2112 bytes (2048 + 64 bytes)
> block size: 1056 words (1024 + 32 words)
> plane size: 2 planes x 1024 blocks per plane
> device size: 2Gb: 2048 blocks
> ecc: 4bit
>
> The legacy_set_geometry function comes up with:
> gf_len=13
> ecc_strength=8
> page_size=2112
> metadata_size=10
> ecc_chunk_size=512
> ecc_chunk_count=4
> payload_size=2048
> auxiliary_size=16
> auxiliary_status_offset=12
> block_mark_byte_offset=1999
>
> and the new set_geometry_by_ecc_info comes up with:
> gf_len=13
> ecc_strength=4
> page_size=2084
> metadata_size=10
> ecc_chunk_size=512
> ecc_chunk_count=4
> payload_size=2048
> auxiliary_size=16
> auxiliary_status_offset=12
> block_mark_byte_offset=2018
> block_mark_bit_offset=4
>
> There are two discrepancies above:
>   a) ecc_strength - this part has 4bit ecc but being detected as 8?
>   b) page_size - the legacy function includes oob in page size, and the
> new one does not
>
> which is correct?
>
In theory, both are correct.

I am in an embarrass state now:
[1] we can support the jffs2, when we use the set_geometry_by_ecc_info() 
to set the NAND layout.

[2] if we still use the legacy_set_geometry() to set the NAND layout, we 
can not support the jffs2 for GPMI.


When i submitted the gpmi to the kernel, the mtd code can not provide me 
the ECC info. I had to use all the OOB
with legacy_set_geometry(). After i submitted several patches for mtd, 
it can provide us the ECC info now, so i switch
to use the set_geometry_by_ecc_info().

it's easy to fix your problem with a patch like this:
-----------------------------------------------------------------------------------------------------------------

drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    3 ++-
  1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand
index 5a1bbc7..8eeead6 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -352,7 +352,8 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)

  int common_nfc_set_geometry(struct gpmi_nand_data *this)
  {
-       return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
+       return (legacy_set_geometry(this) == 0) ? 0 :
+               set_geometry_by_ecc_info(this);
  }

  struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)


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

But after apply this patch, the gpmi may can not support the JFFS2 any more.

thanks
Huang Shijie



> With your patch using the new function to detect ECC from the part,
> booting to a ubifs that was flashed with uboot (which incidentally
> also set ecc_strength=8) I get endless ECC failures:
>
> [    3.946205] UBI: attaching mtd2 to ubi0
> [    3.946585] UBI warning: ubi_io_read: error -74 (ECC error) while
> reading 64 bytes from PEB 0:0, read only 64 bytes, retry
> [    3.946785] UBI warning: ubi_io_read: error -74 (ECC error) while
> reading 64 bytes from PEB 0:0, read only 64 bytes, retry
> [    3.946983] UBI warning: ubi_io_read: error -74 (ECC error) while
> reading 64 bytes from PEB 0:0, read only 64 bytes, retry
> [    3.947177] UBI error: ubi_io_read: error -74 (ECC error) while
> reading 64 bytes from PEB 0:0, read 64 bytes
> [    3.947186] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.12.0-rc3+ #253
> [    3.947192] Backtrace:
> [    3.947220] [<8001265c>] (dump_backtrace+0x0/0x10c) from
> [<800127fc>] (show_stack+0x18/0x1c)
> [    3.947230]  r6:00000040 r5:ffffffb6 r4:00000000 r3:00000000
> [    3.947247] [<800127e4>] (show_stack+0x0/0x1c) from [<80661820>]
> (dump_stack+0x78/0x94)
> [    3.947269] [<806617a8>] (dump_stack+0x0/0x94) from [<803b4ebc>]
> (ubi_io_read+0x12c/0x364)
> [    3.947274]  r4:bf09e000 r3:00000000
> [    3.947285] [<803b4d90>] (ubi_io_read+0x0/0x364) from [<803b533c>]
> (ubi_io_read_ec_hdr+0x60/0x330)
> [    3.947295] [<803b52dc>] (ubi_io_read_ec_hdr+0x0/0x330) from
> [<803bb2dc>] (ubi_attach+0x160/0x15f0)
> [    3.947304] [<803bb17c>] (ubi_attach+0x0/0x15f0) from [<803ae5f0>]
> (ubi_attach_mtd_dev+0x794/0xf18)
> [    3.947319] [<803ade5c>] (ubi_attach_mtd_dev+0x0/0xf18) from
> [<808d9850>] (ubi_init+0x1f8/0x2bc)
> [    3.947330] [<808d9658>] (ubi_init+0x0/0x2bc) from [<80008880>]
> (do_one_initcall+0xdc/0x194)
> [    3.947342] [<800087a4>] (do_one_initcall+0x0/0x194) from
> [<808aeb94>] (kernel_init_freeable+0x104/0x1d0)
> [    3.952386] [<808d9658>] (ubi_init+0x0/0x2bc) from [<80008880>]
> (do_one_initcall+0xdc/0x194)
> [    3.960828] [<800087a4>] (do_one_initcall+0x0/0x194) from
> [<808aeb94>] (kernel_init_freeable+0x104/0x1d0)
> [    3.967418] [<800087a4>] (do_one_initcall+0x0/0x194) from
> [<808aeb94>] (kernel_init_freeable+0x104/0x1d0)
> [    3.967426] [<808aea90>] (kernel_init_freeable+0x0/0x1d0) from
> [<8065c74c>] (kernel_init+0x10/0xec)
>
> Ideas?
>
> Thanks,
>
> Tim
>




From prabhakar at freescale.com  Sun Oct 20 23:33:15 2013
From: prabhakar at freescale.com (Prabhakar Kushwaha)
Date: Mon, 21 Oct 2013 09:03:15 +0530
Subject: [PATCH] driver/mtd/IFC: Add support of 8K page size NAND flash
In-Reply-To: <1380021083-15986-1-git-send-email-prabhakar@freescale.com>
References: <1380021083-15986-1-git-send-email-prabhakar@freescale.com>
Message-ID: <5264A07B.7000104@freescale.com>

Hi Artem ,

This patch is present in upstream review list from a long time.
There are no review comments.

So, I request you to pick this patch for linux-mtd.git repository.

Regards,
Prabhakar


On 09/24/2013 04:41 PM, Prabhakar Kushwaha wrote:
> Current IFC driver supports till 4K page size NAND flash.
> Add support of 8K Page size NAND flash
>    - Add nand_ecclayout for 4 bit & 8 bit ecc
>    - Defines constants
>    - also fix ecc.strength for 8bit ecc of 8K page size NAND
>
> Signed-off-by: Prabhakar Kushwaha <prabhakar at freescale.com>
> ---
>   git://git.infradead.org/linux-mtd.git branch master
>   
>   arch/powerpc/include/asm/fsl_ifc.h |    2 +
>   drivers/mtd/nand/fsl_ifc_nand.c    |   77 ++++++++++++++++++++++++++++++++++++
>   2 files changed, 79 insertions(+)
>
> diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h
> index b8a4b9b..f49ddb1 100644
> --- a/arch/powerpc/include/asm/fsl_ifc.h
> +++ b/arch/powerpc/include/asm/fsl_ifc.h
> @@ -93,6 +93,7 @@
>   #define CSOR_NAND_PGS_512		0x00000000
>   #define CSOR_NAND_PGS_2K		0x00080000
>   #define CSOR_NAND_PGS_4K		0x00100000
> +#define CSOR_NAND_PGS_8K		0x00180000
>   /* Spare region Size */
>   #define CSOR_NAND_SPRZ_MASK		0x0000E000
>   #define CSOR_NAND_SPRZ_SHIFT		13
> @@ -102,6 +103,7 @@
>   #define CSOR_NAND_SPRZ_210		0x00006000
>   #define CSOR_NAND_SPRZ_218		0x00008000
>   #define CSOR_NAND_SPRZ_224		0x0000A000
> +#define CSOR_NAND_SPRZ_CSOR_EXT		0x0000C000
>   /* Pages Per Block */
>   #define CSOR_NAND_PB_MASK		0x00000700
>   #define CSOR_NAND_PB_SHIFT		8
> diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
> index 317a771..a14885b 100644
> --- a/drivers/mtd/nand/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/fsl_ifc_nand.c
> @@ -135,6 +135,69 @@ static struct nand_ecclayout oob_4096_ecc8 = {
>   	.oobfree = { {2, 6}, {136, 82} },
>   };
>   
> +/* 8192-byte page size with 4-bit ECC */
> +static struct nand_ecclayout oob_8192_ecc4 = {
> +	.eccbytes = 128,
> +	.eccpos = {
> +		8, 9, 10, 11, 12, 13, 14, 15,
> +		16, 17, 18, 19, 20, 21, 22, 23,
> +		24, 25, 26, 27, 28, 29, 30, 31,
> +		32, 33, 34, 35, 36, 37, 38, 39,
> +		40, 41, 42, 43, 44, 45, 46, 47,
> +		48, 49, 50, 51, 52, 53, 54, 55,
> +		56, 57, 58, 59, 60, 61, 62, 63,
> +		64, 65, 66, 67, 68, 69, 70, 71,
> +		72, 73, 74, 75, 76, 77, 78, 79,
> +		80, 81, 82, 83, 84, 85, 86, 87,
> +		88, 89, 90, 91, 92, 93, 94, 95,
> +		96, 97, 98, 99, 100, 101, 102, 103,
> +		104, 105, 106, 107, 108, 109, 110, 111,
> +		112, 113, 114, 115, 116, 117, 118, 119,
> +		120, 121, 122, 123, 124, 125, 126, 127,
> +		128, 129, 130, 131, 132, 133, 134, 135,
> +	},
> +	.oobfree = { {2, 6}, {136, 208} },
> +};
> +
> +/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
> +static struct nand_ecclayout oob_8192_ecc8 = {
> +	.eccbytes = 256,
> +	.eccpos = {
> +		8, 9, 10, 11, 12, 13, 14, 15,
> +		16, 17, 18, 19, 20, 21, 22, 23,
> +		24, 25, 26, 27, 28, 29, 30, 31,
> +		32, 33, 34, 35, 36, 37, 38, 39,
> +		40, 41, 42, 43, 44, 45, 46, 47,
> +		48, 49, 50, 51, 52, 53, 54, 55,
> +		56, 57, 58, 59, 60, 61, 62, 63,
> +		64, 65, 66, 67, 68, 69, 70, 71,
> +		72, 73, 74, 75, 76, 77, 78, 79,
> +		80, 81, 82, 83, 84, 85, 86, 87,
> +		88, 89, 90, 91, 92, 93, 94, 95,
> +		96, 97, 98, 99, 100, 101, 102, 103,
> +		104, 105, 106, 107, 108, 109, 110, 111,
> +		112, 113, 114, 115, 116, 117, 118, 119,
> +		120, 121, 122, 123, 124, 125, 126, 127,
> +		128, 129, 130, 131, 132, 133, 134, 135,
> +		136, 137, 138, 139, 140, 141, 142, 143,
> +		144, 145, 146, 147, 148, 149, 150, 151,
> +		152, 153, 154, 155, 156, 157, 158, 159,
> +		160, 161, 162, 163, 164, 165, 166, 167,
> +		168, 169, 170, 171, 172, 173, 174, 175,
> +		176, 177, 178, 179, 180, 181, 182, 183,
> +		184, 185, 186, 187, 188, 189, 190, 191,
> +		192, 193, 194, 195, 196, 197, 198, 199,
> +		200, 201, 202, 203, 204, 205, 206, 207,
> +		208, 209, 210, 211, 212, 213, 214, 215,
> +		216, 217, 218, 219, 220, 221, 222, 223,
> +		224, 225, 226, 227, 228, 229, 230, 231,
> +		232, 233, 234, 235, 236, 237, 238, 239,
> +		240, 241, 242, 243, 244, 245, 246, 247,
> +		248, 249, 250, 251, 252, 253, 254, 255,
> +		256, 257, 258, 259, 260, 261, 262, 263,
> +	},
> +	.oobfree = { {2, 6}, {264, 80} },
> +};
>   
>   /*
>    * Generic flash bbt descriptors
> @@ -872,11 +935,25 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
>   		} else {
>   			layout = &oob_4096_ecc8;
>   			chip->ecc.bytes = 16;
> +			chip->ecc.strength = 8;
>   		}
>   
>   		priv->bufnum_mask = 1;
>   		break;
>   
> +	case CSOR_NAND_PGS_8K:
> +		if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
> +		    CSOR_NAND_ECC_MODE_4) {
> +			layout = &oob_8192_ecc4;
> +		} else {
> +			layout = &oob_8192_ecc8;
> +			chip->ecc.bytes = 16;
> +			chip->ecc.strength = 8;
> +		}
> +
> +		priv->bufnum_mask = 0;
> +	break;
> +
>   	default:
>   		dev_err(priv->dev, "bad csor %#x: bad page size\n", csor);
>   		return -ENODEV;





From prabhakar at freescale.com  Sun Oct 20 23:34:12 2013
From: prabhakar at freescale.com (Prabhakar Kushwaha)
Date: Mon, 21 Oct 2013 09:04:12 +0530
Subject: [PATCH] driver/mtd/ifc: Read Status while programming NAND flash
In-Reply-To: <1380780401-6640-1-git-send-email-prabhakar@freescale.com>
References: <1380780401-6640-1-git-send-email-prabhakar@freescale.com>
Message-ID: <5264A0B4.1050300@freescale.com>

Hi Artem,

This patch is present in upstream review list from a long time.
There are no review comments.

So, I request you to pick this patch for linux-mtd.git repository.

Regards,
Prabhakar


On 10/03/2013 11:36 AM, Prabhakar Kushwaha wrote:
> as per controller description,
>    "While programming a NAND flash, status read should never skipped.
>     Because it may happen that a new command is issued to the NAND Flash,
>     even when the device has not yet finished processing the previous request.
>     This may result in unpredictable behaviour."
>
> IFC controller never polls for R/B signal after command send. It just return
> control to software. This behaviour may not occur with NAND flash access.
> because new commands are sent after polling R/B signal. But it may happen
> in scenario where GPCM-ASIC and NAND flash device are working simultaneously.
>
> Update the controller driver to take care of this requirement
>
> Signed-off-by: Prabhakar Kushwaha <prabhakar at freescale.com>
> ---
>   drivers/mtd/nand/fsl_ifc_nand.c |   34 ++++++++++++++++++++++++----------
>   1 file changed, 24 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
> index a14885b..eb150f1 100644
> --- a/drivers/mtd/nand/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/fsl_ifc_nand.c
> @@ -504,20 +504,29 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
>   		if (mtd->writesize > 512) {
>   			nand_fcr0 =
>   				(NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) |
> -				(NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT);
> +				(NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) |
> +				(NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);
>   
>   			iowrite32be(
> -				(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
> -				(IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
> -				(IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
> -				(IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP3_SHIFT) |
> -				(IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT),
> -				&ifc->ifc_nand.nand_fir0);
> +				 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
> +				 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |
> +				 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |
> +				 (IFC_FIR_OP_WBCD  << IFC_NAND_FIR0_OP3_SHIFT) |
> +				 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT),
> +				 &ifc->ifc_nand.nand_fir0);
> +			iowrite32be(
> +				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) |
> +				 (IFC_FIR_OP_RDSTAT <<
> +					IFC_NAND_FIR1_OP6_SHIFT) |
> +				 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT),
> +				 &ifc->ifc_nand.nand_fir1);
>   		} else {
>   			nand_fcr0 = ((NAND_CMD_PAGEPROG <<
>   					IFC_NAND_FCR0_CMD1_SHIFT) |
>   				    (NAND_CMD_SEQIN <<
> -					IFC_NAND_FCR0_CMD2_SHIFT));
> +					IFC_NAND_FCR0_CMD2_SHIFT) |
> +				    (NAND_CMD_STATUS <<
> +					IFC_NAND_FCR0_CMD3_SHIFT));
>   
>   			iowrite32be(
>   				(IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |
> @@ -526,8 +535,13 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
>   				(IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |
>   				(IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT),
>   				&ifc->ifc_nand.nand_fir0);
> -			iowrite32be(IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT,
> -				    &ifc->ifc_nand.nand_fir1);
> +			iowrite32be(
> +				 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) |
> +				 (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) |
> +				 (IFC_FIR_OP_RDSTAT <<
> +					IFC_NAND_FIR1_OP7_SHIFT) |
> +				 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT),
> +				  &ifc->ifc_nand.nand_fir1);
>   
>   			if (column >= mtd->writesize)
>   				nand_fcr0 |=





From b32955 at freescale.com  Sun Oct 20 23:40:16 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 21 Oct 2013 11:40:16 +0800
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>	<5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
Message-ID: <5264A220.2070900@freescale.com>

? 2013?10?19? 10:01, Brian Norris ??:
> Yes, I seem to have overlooked this set. I think it must have come in
> parallel with your MLC patch set, so I delayed it until the MLC patch
> set settled down?
>
this patch set has no relationship with MLC patch.

> Anyway, I'll revisit this soon. But I probably need to take care of
> your mtd-utils updates first, since they should go along with the MLC
> patch set.
>
> And on top of that (to update the world on daily status), I seem to be
> tripping over some UBIFS bugs that are inhibiting the validation I'm
> trying to do for some new hardware. So, I'm all-around pretty busy!
> I'll get myself together next week, hopefully.
understood.


I am too busy too, i am starting to code the Qspi driver now.
I was blocked by a bluetooth/uart/dma issue last month.
> In the meantime, other people's code could use some extra eyes. I know
> Ezequiel just sent out a 27 (!) patch series today. There's also the
> pending cmdline.c patch from months ago, where Cai Zhiyong wanted to
> migrate our command line partition parser to a common
> block/cmdline-parser.c. Part of her work (for block devices) is
I like Cai zhiyong's patch. But I do not have time to test his patch.


thanks
Huang Shijie





From pekon at ti.com  Mon Oct 21 02:01:16 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Mon, 21 Oct 2013 06:01:16 +0000
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <5264A220.2070900@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>
 <5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>

Hi Shijie,

> From: Huang Shijie
> 
> I am too busy too, i am starting to code the Qspi driver now.
> 
(1)
Your controller uses LUT based approach, So in case, you are planning to
follow DT based approach of populating flash information in your QSPI
controller then I can help you to put that as part of generic framework
so that both ti-qspi and fsl-qspi can re-use it.

(2) 
Also, would you be interested in deriving generic framework for serial
NOR something like mtd/spinor/.. where m25p80 can plug-in ?

Based on the following cleaned up version of mtd/spinand/...
https://lkml.org/lkml/2013/6/26/88
by Mona Anonuevo <manonuevo at micron.com>


with regards, pekon


From computersforpeace at gmail.com  Mon Oct 21 03:21:24 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 21 Oct 2013 00:21:24 -0700
Subject: gpmi-mtd ecc regression
In-Reply-To: <52649FDA.1030804@freescale.com>
References: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
 <52649FDA.1030804@freescale.com>
Message-ID: <CAN8TOE9+ez=t-1n+jd5d3tu+EB9YJKFeM2RKAHBf059L5TYM7A@mail.gmail.com>

On Sun, Oct 20, 2013 at 8:30 PM, Huang Shijie <b32955 at freescale.com> wrote:
> ? 2013?10?19? 01:03, Tim Harvey ??:
>>
>> The patch you made to obtain ECC info from the chip
>>
>> (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/mtd/nand/gpmi-nand?id=2febcdf84b75aae627c61f0a5bf531a69299966c)
>> has caused a regression for an i.MX6 board I'm working with that uses
>> NAND and ubifs.

...

> I am in an embarrass state now:
> [1] we can support the jffs2, when we use the set_geometry_by_ecc_info() to
> set the NAND layout.
>
> [2] if we still use the legacy_set_geometry() to set the NAND layout, we can
> not support the jffs2 for GPMI.
>
>
> When i submitted the gpmi to the kernel, the mtd code can not provide me the
> ECC info. I had to use all the OOB
> with legacy_set_geometry(). After i submitted several patches for mtd, it
> can provide us the ECC info now, so i switch
> to use the set_geometry_by_ecc_info().
>
> it's easy to fix your problem with a patch like this:
> -----------------------------------------------------------------------------------------------------------------
>
> drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> b/drivers/mtd/nand/gpmi-nand
> index 5a1bbc7..8eeead6 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -352,7 +352,8 @@ static int legacy_set_geometry(struct gpmi_nand_data
> *this)
>
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> -       return set_geometry_by_ecc_info(this) ? 0 :
> legacy_set_geometry(this);
> +       return (legacy_set_geometry(this) == 0) ? 0 :
> +               set_geometry_by_ecc_info(this);
>  }
>
>  struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
>
>
> -----------------------------------------------------------------------------------------------------------------

So you really have two wholly incompatible layout methods, one which
targeted using the maximum ECC strength that fits and one which
targets the minimum required ECC strength? It seems that you can only
use a new ECC/geometry if the user prompts you to do so (via device
tree, for instance). Doing otherwise is bound to create regressions
like this.

> But after apply this patch, the gpmi may can not support the JFFS2 any more.

Well, we do prioritize "no regressions", rather than new features. So
we may have to do this until a proper solution can be formed.

Brian


From b32955 at freescale.com  Mon Oct 21 04:04:07 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 21 Oct 2013 16:04:07 +0800
Subject: gpmi-mtd ecc regression
In-Reply-To: <CAN8TOE9+ez=t-1n+jd5d3tu+EB9YJKFeM2RKAHBf059L5TYM7A@mail.gmail.com>
References: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>	<52649FDA.1030804@freescale.com>
 <CAN8TOE9+ez=t-1n+jd5d3tu+EB9YJKFeM2RKAHBf059L5TYM7A@mail.gmail.com>
Message-ID: <5264DFF7.2090702@freescale.com>

? 2013?10?21? 15:21, Brian Norris ??:
> Well, we do prioritize "no regressions", rather than new features. So
> we may have to do this until a proper solution can be formed.
ok.

I will create a patch to fix this regression.
And it seems i have to add new devicetree property to enable the JFFS2
support.

thanks
Huang Shijie



From b32955 at freescale.com  Mon Oct 21 04:32:41 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 21 Oct 2013 16:32:41 +0800
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>	<5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>
Message-ID: <5264E6A9.6070400@freescale.com>

? 2013?10?21? 14:01, Gupta, Pekon ??:
> Hi Shijie,
>
>> From: Huang Shijie
>>
>> I am too busy too, i am starting to code the Qspi driver now.
>>
> (1)
> Your controller uses LUT based approach, So in case, you are planning to
> follow DT based approach of populating flash information in your QSPI
> controller then I can help you to put that as part of generic framework
> so that both ti-qspi and fsl-qspi can re-use it.
it's very good.
> (2)
> Also, would you be interested in deriving generic framework for serial
> NOR something like mtd/spinor/.. where m25p80 can plug-in ?

yes.

Do you have any solution about the generic framework for spi nor?

i want to chage the m25p80.c, and make it not only work for SPI drivers, 
but also can work for SPI-NOR(QSPI) driver.

thanks
Huang Shijie


> Based on the following cleaned up version of mtd/spinand/...
> https://lkml.org/lkml/2013/6/26/88
> by Mona Anonuevo<manonuevo at micron.com>
>
>
> with regards, pekon
>




From pekon at ti.com  Mon Oct 21 05:02:59 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Mon, 21 Oct 2013 09:02:59 +0000
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <5264E6A9.6070400@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>
 <5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>
 <5264E6A9.6070400@freescale.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA29221@DBDE04.ent.ti.com>

Hi,

> From: Huang Shijie [mailto:b32955 at freescale.com]
> ? 2013?10?21? 14:01, Gupta, Pekon ??:
> > Hi Shijie,
> >
> >> From: Huang Shijie
> >>
> >> I am too busy too, i am starting to code the Qspi driver now.
> >>
> > (1)
> > Your controller uses LUT based approach, So in case, you are planning to
> > follow DT based approach of populating flash information in your QSPI
> > controller then I can help you to put that as part of generic framework
> > so that both ti-qspi and fsl-qspi can re-use it.
> it's very good.
> > (2)
> > Also, would you be interested in deriving generic framework for serial
> > NOR something like mtd/spinor/.. where m25p80 can plug-in ?
> 
> yes.
> 
> Do you have any solution about the generic framework for spi nor?
> 
> i want to chage the m25p80.c, and make it not only work for SPI drivers,
> but also can work for SPI-NOR(QSPI) driver.
> 
Thanks, but in that case, please do not add generic code in m25p80.c.
Let it live as driver for NOR devices, because it supports too many other
devices. Rather I was thinking on following ways:

* Step-1: define an interface between SPI-NOR and MTD *
+ create include/linux/mtd/spinor.h
struct spinor {
	/* modes */
	enum modes { MM_MODE, SPI_MODE };
	/* erase operation */	
	uint32 erase_opcode;
	uint32 erase_dummy_cycles;
	int (* erase_done) (...);
	/* read operation */
	uint32 read_opcode;
	uint32 read_dummy_cycles;
	int (*read_done) (...);
	/* write operation */
	[...]
}
This is similar to struct nand_chip in include/linux/mtd/nand.h
But specific to SPI NOR device attributes.


* Step-2:  spawn out generic code from m25p80 into generic framework *
_(maintaining original authorship)_
+ create /driver/mtd/spinor/spinor.c
m25p80_erase() -> spinor_erase(mtd, ...)
m25p80_read() -> spinor_read( mtd, from, len, *buf, ... )
m25p80_write() -> spinor_write (mtd, to, len, *buf, ... )

If you already have done some work on m25p80.c then please see if
you can convert on above thoughts and post it. I'll review them and
add more stuff and cleanups. 
Else, I plan to do that from scratch but need sometime, as I'm bit stuck
in some omap2-nand driver clean-up activities.
Let me know what suits you, as per your QSPI-FSL driver timelines..


with regards, pekon

From annulen at yandex.ru  Mon Oct 21 05:49:57 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Mon, 21 Oct 2013 13:49:57 +0400
Subject: [PATCH v1] mtd-utils:mkfs.ubifs: Add support for LZ4HC compression
In-Reply-To: <CAGWqfiip3ZXvS9K7LxOEoGy3J=+a81q=9L3Gz8FvoLCReO-LCg@mail.gmail.com>
References: <CAGWqfiip3ZXvS9K7LxOEoGy3J=+a81q=9L3Gz8FvoLCReO-LCg@mail.gmail.com>
Message-ID: <242431382348997@web1g.yandex.ru>



07.10.2013, 22:59, "Elie De Brauwer" <eliedebrauwer at gmail.com>:
> All,
>
> After some more experimentation and some input from Konstantin
> attached is a new version of a patch to mtd-utils which adds LZ4HC
> support to mkfs.ubifs:
>
> What's new:
> ?- favor_lz4hc is changed to toggle between lz4hc/lzo rather than
> lz4hc/zlib in order to come up with a mode which should be both flash
> and cpu friendly, mainly since our experiments showed that lz4hc isn't
> a free lunch by default (read: probably starts paying of at larger
> block lengths than what we can offer it now).
>
> Some tests of this new mode at different favor-percents shows that for
> my little rootfs that with a favor percent of 10%, lz4hc gets used in
> about 17% of the cases with a footprint which is within a meg's range
> of what lzo would've done to it.
>
> edb at lapelidb:~/mtd-utils$ for x in 20 15 10 7 5 3; do ?echo $x; sudo
> mkfs.ubifs/mkfs.ubifs ?-X $x -x favor_lz4hc -m 2048 -e 126976 -c 744
> -d /tmp/k/ /tmp/imag.favor_lz4hc_$x | sort | uniq -c; ls -hal
> /tmp/imag.favor_lz4hc_$x ; done

Side note: there is no need to run mkfs.ubifs under root. Just add
/usr/sbin or /usr/local/sbin to your path.

-- 
Regards,
Konstantin


From annulen at yandex.ru  Mon Oct 21 11:59:20 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Mon, 21 Oct 2013 19:59:20 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
Message-ID: <183031382371160@web6m.yandex.ru>



04.10.2013, 07:09, "Brent Taylor" <motobud at gmail.com>:
> Here is a patch based on linux-3.12-rc3. ?I haven't performed any
> performance testing UBIFS using lz4hc, but I can mount UBIFS volumes
> and haven't seen any problems yet. ?The only think I know that isn't
> correct about the patch is the description for the Kconfig element for
> select lz4hc as a compression option. ?I only copied the description
> from the lzo description.

Hi Brent,

I'm testing your patch on my SH4 device. When I create new partition
with lz4hc compressor, it works fine: I can copy file into it, and
md5sums of original and copy match. However, after reboot I cannot
read the file anymore:

UBIFS error (pid 1101): ubifs_decompress: cannot decompress 934 bytes, compressor lz4hc, error -22
UBIFS error (pid 1101): read_block: bad data node (block 1, inode 65)
UBIFS error (pid 1101): do_readpage: cannot read page 1 of inode 65, error -22

The same error appears if I use lz4hc-compressed ubifs image to flash rootfs
(using patched mkfs.ubifs).

Decompression error occurs in lz4_uncompress() function (lib/lz4/lz4_decompress.c),
on the line 101:

/* Error: offset create reference outside destination buffer */
if (unlikely(ref < (BYTE *const) dest))
    goto _output_error;

Brent: are you able to read data from lz4hc volume on your device?
Anyone: any ideas what may happen here?

-- 
Regards,
Konstantin


From computersforpeace at gmail.com  Mon Oct 21 13:41:17 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 21 Oct 2013 10:41:17 -0700
Subject: gpmi-mtd ecc regression
In-Reply-To: <5264DFF7.2090702@freescale.com>
References: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
 <52649FDA.1030804@freescale.com>
 <CAN8TOE9+ez=t-1n+jd5d3tu+EB9YJKFeM2RKAHBf059L5TYM7A@mail.gmail.com>
 <5264DFF7.2090702@freescale.com>
Message-ID: <CAN8TOE-swY_uA3u3OBt3ip-F=s3_H5hDZE=uDE5VNBGCeZc-XA@mail.gmail.com>

On Mon, Oct 21, 2013 at 1:04 AM, Huang Shijie <b32955 at freescale.com> wrote:
> ? 2013?10?21? 15:21, Brian Norris ??:
>> Well, we do prioritize "no regressions", rather than new features. So
>> we may have to do this until a proper solution can be formed.
> ok.
>
> I will create a patch to fix this regression.

Yes. We should either get it into 3.12 or mark it -stable.

> And it seems i have to add new devicetree property to enable the JFFS2
> support.

We cannot use device-tree to enable JFFS2 (a purely software issue),
but you could use it to specify the ECC strength or layout. Be sure to
CC devicetree at vger.kernel.org on any new bindings, since they need to
review bindings and tend to have good input.

Brian


From computersforpeace at gmail.com  Mon Oct 21 13:48:03 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 21 Oct 2013 10:48:03 -0700
Subject: [PATCH] mtd: nand: use a local variable to simplify the
 nand_scan_tail
In-Reply-To: <20131020105359.GA2465@localhost>
References: <1382077253-21709-1-git-send-email-b32955@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2866E@DBDE04.ent.ti.com>
 <20131019130846.GB2470@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA28EB9@DBDE04.ent.ti.com>
 <20131020105359.GA2465@localhost>
Message-ID: <CAN8TOE8btxKEhKGX-wVD5Bo2UcsouHSWSLZjYPqn+R-jiXj5Zw@mail.gmail.com>

On Sun, Oct 20, 2013 at 3:54 AM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> On Sun, Oct 20, 2013 at 07:01:11AM +0000, Gupta, Pekon wrote:
>> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
>> > > On Fri, Oct 18, 2013 at 02:11:19PM +0000, Gupta, Pekon wrote:
>> > > Personally I won't prefer such stand-alone cleanup  _unless_ there is
>> > > major driver re-write of the code, because this breaks the traceability
>> > > via 'git blame'. And even in that case, this change should be applied first,
>> > > and the other functional updates later.
>> > >
>> >
>> > Hm.. I'm not sure I agree here. I like this patch and I like the effect
>> > it has on nand_scan_tail().
>> >
>> > On a personal note, I hardly ever use git blame at all (because it's dead
>> > slow). Instead, I just run git log ${file} and get the latest changes on
>> > that file.
>> >
>> Its rather difficult to use 'git log' especially when you are tracing or debugging
>> a generic driver, and want to know why this piece of code was introduced,
>> and the idea behind it. 'git log' won?t show line by line commit details.
>
> Quite the opposite 'git log --patch' shows the commit details.
> Or maybe you need something that I'm not aware of?
>
> I really don't think we should dis-encourage cleanups -in what ever form
> and time they might come- just to preserve the last 'major' author of a file.

I'm fairly neutral regarding the value of this particular patch (it
doesn't add a lot of value to me) but I agree with Ezequiel's
sentiment. Unless we have a stronger reason for avoiding this change,
I will probably take it.

Brian


From computersforpeace at gmail.com  Mon Oct 21 14:15:53 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Mon, 21 Oct 2013 11:15:53 -0700
Subject: [PATCH] mtd: nand: hack ONFI for non-power-of-2 dimensions
In-Reply-To: <1377656358-7053-1-git-send-email-computersforpeace@gmail.com>
References: <1377656358-7053-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131021181553.GJ23337@ld-irv-0074.broadcom.com>

On Tue, Aug 27, 2013 at 07:19:18PM -0700, Brian Norris wrote:
> Some bright specification writers decided to write this in the ONFI spec
> (from ONFI 3.0, Section 3.1):
> 
>   "The number of blocks and number of pages per block is not required to
>   be a power of two. In the case where one of these values is not a
>   power of two, the corresponding address shall be rounded to an
>   integral number of bits such that it addresses a range up to the
>   subsequent power of two value. The host shall not access upper
>   addresses in a range that is shown as not supported."
> 
> This breaks every assumption MTD makes about NAND block/chip-size
> dimensions -- they *must* be a power of two!
> 
> And of course, an enterprising manufacturer has made use of this lovely
> freedom. Exhibit A: Micron MT29F32G08CBADAWP
> 
>   "- Plane size: 2 planes x 1064 blocks per plane
>    - Device size: 32Gb: 2128 blockss [sic]"
> 
> This quickly hits a BUG() in nand_base.c, since the extra dimensions
> overflow so we think it's a second chip (on my single-chip setup):
> 
>     ONFI param page 0 valid
>     ONFI flash detected
>     NAND device: Manufacturer ID: 0x2c, Chip ID: 0x44 (Micron MT29F32G08CBADAWP), 4256MiB, page size: 8192, OOB size: 744
>     ------------[ cut here ]------------
>     kernel BUG at drivers/mtd/nand/nand_base.c:203!
>     Internal error: Oops - BUG: 0 [#1] SMP ARM
>     [... trim ...]
>     [<c02cf3e4>] (nand_select_chip+0x18/0x2c) from [<c02d25c0>] (nand_do_read_ops+0x90/0x424)
>     [<c02d25c0>] (nand_do_read_ops+0x90/0x424) from [<c02d2dd8>] (nand_read+0x54/0x78)
>     [<c02d2dd8>] (nand_read+0x54/0x78) from [<c02ad2c8>] (mtd_read+0x84/0xbc)
>     [<c02ad2c8>] (mtd_read+0x84/0xbc) from [<c02d4b28>] (scan_read.clone.4+0x4c/0x64)
>     [<c02d4b28>] (scan_read.clone.4+0x4c/0x64) from [<c02d4c88>] (search_bbt+0x148/0x290)
>     [<c02d4c88>] (search_bbt+0x148/0x290) from [<c02d4ea4>] (nand_scan_bbt+0xd4/0x5c0)
>     [... trim ...]
>     ---[ end trace 0c9363860d865ff2 ]---
> 
> So to fix this, just truncate these dimensions down to the greatest
> power-of-2 dimension that is less than or equal to the specified
> dimension.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Cc: <stable at vger.kernel.org>

I've not heard any comments about this, but I've been using this patch
for a few months on most of my kernels, and I just ran into another
(unpatched) kernel/board that trips over this same problem. Unless
someone screams...

... applied to l2-mtd.git, with CC -stable. Although it is a bugfix, I
think it should wait until next merge window so it can sit in -next for
a while.

Brian


From zajec5 at gmail.com  Mon Oct 21 16:34:37 2013
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 21 Oct 2013 22:34:37 +0200
Subject: [RESEND][PATCH V2] mtd: bcm47xxpart: detect block aligned Squashfs
 partition
Message-ID: <1382387677-22006-1-git-send-email-zajec5@gmail.com>

Most of the bcm47xx devices use TRX format for storing kernel and some
partition like Squashfs or JFFS2. This is pretty flexible solution, CFE
(the bootloader) just writes (and later boots) TRX at some hardcoded
place and paritions can vary in the size.

However some devices don't use TRX format. Very recently we have
discovered ZTE H218N that has kernel and rootfs partitions at some
"random" places.

This patch allows Linux find a rootfs partition after installing custom
image with a CFE bootloader.

Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
---
 drivers/mtd/bcm47xxpart.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index 9279a91..61213f9 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -32,6 +32,7 @@
 #define ML_MAGIC1			0x39685a42
 #define ML_MAGIC2			0x26594131
 #define TRX_MAGIC			0x30524448
+#define SQSH_MAGIC			0x71736873	/* shsq */
 
 struct trx_header {
 	uint32_t magic;
@@ -167,6 +168,13 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 			offset = rounddown(offset + trx->length, blocksize);
 			continue;
 		}
+
+		/* Squashfs on devices not using TRX */
+		if (buf[0x000 / 4] == SQSH_MAGIC) {
+			bcm47xxpart_add_part(&parts[curr_part++], "rootfs",
+					     offset, 0);
+			continue;
+		}
 	}
 
 	/* Look for NVRAM at the end of the last block. */
-- 
1.7.10.4



From zajec5 at gmail.com  Mon Oct 21 16:35:34 2013
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 21 Oct 2013 22:35:34 +0200
Subject: [RESEND][PATCH] mtd: bcm47xxpart: detect "factory" partition
Message-ID: <1382387734-22049-1-git-send-email-zajec5@gmail.com>

A new type of partition with magic FCTY was found on Huawei E970:
46 43 54 59 4b 51 37 4e  41 42 31 38 41 32 39 30  |FCTYKQ7NAB18A290|

Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>
---
 drivers/mtd/bcm47xxpart.c |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
index 61213f9..20ef301 100644
--- a/drivers/mtd/bcm47xxpart.c
+++ b/drivers/mtd/bcm47xxpart.c
@@ -27,6 +27,7 @@
 
 /* Magics */
 #define BOARD_DATA_MAGIC		0x5246504D	/* MPFR */
+#define FACTORY_MAGIC			0x59544346	/* FCTY */
 #define POT_MAGIC1			0x54544f50	/* POTT */
 #define POT_MAGIC2			0x504f		/* OP */
 #define ML_MAGIC1			0x39685a42
@@ -111,6 +112,13 @@ static int bcm47xxpart_parse(struct mtd_info *master,
 			continue;
 		}
 
+		/* Found on Huawei E970 */
+		if (buf[0x000 / 4] == FACTORY_MAGIC) {
+			bcm47xxpart_add_part(&parts[curr_part++], "factory",
+					     offset, MTD_WRITEABLE);
+			continue;
+		}
+
 		/* POT(TOP) */
 		if (buf[0x000 / 4] == POT_MAGIC1 &&
 		    (buf[0x004 / 4] & 0xFFFF) == POT_MAGIC2) {
-- 
1.7.10.4



From motobud at gmail.com  Mon Oct 21 23:43:52 2013
From: motobud at gmail.com (Brent Taylor)
Date: Mon, 21 Oct 2013 22:43:52 -0500
Subject: lz4hc compression in UBIFS?
In-Reply-To: <183031382371160@web6m.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <183031382371160@web6m.yandex.ru>
Message-ID: <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>

On Mon, Oct 21, 2013 at 10:59 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 04.10.2013, 07:09, "Brent Taylor" <motobud at gmail.com>:
>> Here is a patch based on linux-3.12-rc3.  I haven't performed any
>> performance testing UBIFS using lz4hc, but I can mount UBIFS volumes
>> and haven't seen any problems yet.  The only think I know that isn't
>> correct about the patch is the description for the Kconfig element for
>> select lz4hc as a compression option.  I only copied the description
>> from the lzo description.
>
> Hi Brent,
>
> I'm testing your patch on my SH4 device. When I create new partition
> with lz4hc compressor, it works fine: I can copy file into it, and
> md5sums of original and copy match. However, after reboot I cannot
> read the file anymore:
>
> UBIFS error (pid 1101): ubifs_decompress: cannot decompress 934 bytes, compressor lz4hc, error -22
> UBIFS error (pid 1101): read_block: bad data node (block 1, inode 65)
> UBIFS error (pid 1101): do_readpage: cannot read page 1 of inode 65, error -22
>
> The same error appears if I use lz4hc-compressed ubifs image to flash rootfs
> (using patched mkfs.ubifs).
>
> Decompression error occurs in lz4_uncompress() function (lib/lz4/lz4_decompress.c),
> on the line 101:
>
> /* Error: offset create reference outside destination buffer */
> if (unlikely(ref < (BYTE *const) dest))
>     goto _output_error;
>
> Brent: are you able to read data from lz4hc volume on your device?
> Anyone: any ideas what may happen here?
>
> --
> Regards,
> Konstantin

Konstantin,
   I haven't seen anything like that on my at91sam9m10g45-ek
development board.  I haven't used a flash image from mkfs.ubifs yet.
Is it possible the file system was not umounted cleanly before the
reboot and UBIFS went through a recovery procedure?  Maybe something
breaks with lz4hc when UBIFS does a recovery?  That's just a guess.

Regards,
Brent


From pekon at ti.com  Tue Oct 22 01:11:37 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Tue, 22 Oct 2013 05:11:37 +0000
Subject: [PATCH v3 00/10] About the SLC/MLC
In-Reply-To: <20130827033020.GA2182@gmail.com>
References: <1377509808-29363-1-git-send-email-b32955@freescale.com>
 <20130826144153.568f2b1c@skate> <20130827033020.GA2182@gmail.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA297AE@DBDE04.ent.ti.com>

> From:  Huang Shijie
> On Mon, Aug 26, 2013 at 02:41:53PM +0200, Thomas Petazzoni wrote:
> > Dear Huang Shijie,
> >
> > On Mon, 26 Aug 2013 17:36:38 +0800, Huang Shijie wrote:
> > > In current mtd code, the MTD_NANDFLASH is used to represent both the
> > > SLC nand MLC(including the TLC). But we already have the
> MTD_MLCNANDFLASH
> > > to stand for the MLC. What is worse is that the JFFS2 may run on the MLC
> > > nand with current code. For the reason of READ/WRITE disturbance, the
> JFFS2
> > > should runs on the SLC only,
> >
> > Pardon the probably very silly question, but would you mind giving more
> > details about why JFFS2 is not appropriate on MLC flashes? Is there
> > anything that UBI/UBIFS does that JFFS2 isn't doing to take into
> > account read/write disturbance?
> I try to explain it.
> 
> For the UBIFS, it will writes the page(including the oob) only one time;
> but for jffs2, it may writes the page(including the oob) twice, one for the
> marker, one for the real data.
> 
> For the MLC, the write disturbance will cause some bitflips in this
> page. Since you write a page twice, so in the jffs2, you will meet
> uncorrectable
> ECC error.
> 
But, doesn't JFFS2 checks for the blank page before second-write of data ?
UBI does it here..
File: $KERNEL/drivers/mtd/ubi/io.c
@@ubi_io_write (... )
[...]
	err = ubi_self_check_all_ff(ubi, pnum, offset, len);

So, isn't it better to add this check in JFFS2 code so that its more
bit-flips tolerant ?
This way bit-flips caused by first write to OOB (cleanmarker) would be
caught before using that page for data write. And so MLC should also be
good for JFFS2..

with regards, pekon


From b32955 at freescale.com  Tue Oct 22 01:10:28 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Tue, 22 Oct 2013 13:10:28 +0800
Subject: [PATCH] mtd: gpmi: fix the ecc regression
Message-ID: <1382418628-4521-1-git-send-email-b32955@freescale.com>

The patch "2febcdf mtd: gpmi: set the BCHs geometry with the ecc info"
makes the gpmi to use the ECC info provided by the MTD code, and creates
a different NAND ecc layout for the BCH which brings a regression to us:
   We can not mount the ubifs which was created by the old NAND ecc layout.

This patch adds a new property : "fsl,use-mtd-ecc-info".

If we do not enable it, we will use the ecc strength calculated by ourselves
and use all the OOB area (this is the legacy method);

If we enable it, we will use the ecc strength provided by the MTD layer,
and create a new NAND ecc layout which may has free space in the OOB
(for some SLC nand, we may support the JFFS2 with the new NAND ecc layout).

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 .../devicetree/bindings/mtd/gpmi-nand.txt          |    4 ++++
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c             |    7 ++++++-
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index 551b2a1..fe84a3d 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -17,6 +17,10 @@ Required properties:
 Optional properties:
   - nand-on-flash-bbt: boolean to enable on flash bbt option if not
                        present false
+  - fsl,use-mtd-ecc-info: By enabling this boolean property, the gpmi can uses
+                       the MTD's ECC info (if the MTD has). So we may have free
+                       space in the OOB area, and we may support the JFFS2 with
+                       some SLC nand, such as Micron's SLC nand.
 
 The device tree may optionally contain sub-nodes describing partitions of the
 address space. See partition.txt for more detail.
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 5a1bbc7..62c0712 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -271,7 +271,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 		dev_err(this->dev,
 			"We can not support this nand chip."
 			" Its required ecc strength(%d) is beyond our"
-			" capability(%d).\n", geo->ecc_strength,
+			" capability(%d). If you have not enabled the"
+			"'fsl,use-mtd-ecc-info', enable it and try again.\n",
+			geo->ecc_strength,
 			(GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX
 					: MXS_ECC_STRENGTH_MAX));
 		return -EINVAL;
@@ -352,6 +354,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
+	if (!of_property_read_bool(this->dev->of_node, "fsl,use-mtd-ecc-info"))
+		return legacy_set_geometry(this);
+
 	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
 }
 
-- 
1.7.2.rc3




From b32955 at freescale.com  Tue Oct 22 04:16:58 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Tue, 22 Oct 2013 16:16:58 +0800
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA29221@DBDE04.ent.ti.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>	<5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>
 <5264E6A9.6070400@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29221@DBDE04.ent.ti.com>
Message-ID: <5266347A.6060000@freescale.com>

? 2013?10?21? 17:02, Gupta, Pekon ??:
> If you already have done some work on m25p80.c then please see if
> you can convert on above thoughts and post it. I'll review them and
> add more stuff and cleanups.
I will convert my code, and send out as soon as possible.

thanks
Huang Shijie



From sourav.poddar at ti.com  Tue Oct 22 04:34:29 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 22 Oct 2013 14:04:29 +0530
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <5266347A.6060000@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>	<5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>
 <5264E6A9.6070400@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29221@DBDE04.ent.ti.com>
 <5266347A.6060000@freescale.com>
Message-ID: <52663895.9040907@ti.com>

Hi Huang,
On Tuesday 22 October 2013 01:46 PM, Huang Shijie wrote:
> ? 2013?10?21? 17:02, Gupta, Pekon ??:
>> If you already have done some work on m25p80.c then please see if
>> you can convert on above thoughts and post it. I'll review them and
>> add more stuff and cleanups.
> I will convert my code, and send out as soon as possible.
>
> thanks
> Huang Shijie
>
>
Did you get the chance to follow the three patch series which I had sent?
One of the patch modifies m25p80 to add support for spnasion and 
macronix quad read
support. If that looks cool also to you[1], we can push for that patch. 
So that, our further works
on m25p80 will be reduced.

[1]:  http://permalink.gmane.org/gmane.linux.drivers.mtd/48755
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From b32955 at freescale.com  Tue Oct 22 05:03:19 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Tue, 22 Oct 2013 17:03:19 +0800
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <52663895.9040907@ti.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>	<5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2910B@DBDE04.ent.ti.com>
 <5264E6A9.6070400@freescale.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29221@DBDE04.ent.ti.com>
 <5266347A.6060000@freescale.com> <52663895.9040907@ti.com>
Message-ID: <52663F57.5060701@freescale.com>

? 2013?10?22? 16:34, Sourav Poddar ??:
> Hi Huang,
> Did you get the chance to follow the three patch series which I had sent?
> One of the patch modifies m25p80 to add support for spnasion and 
> macronix quad read
> support. If that looks cool also to you[1], we can push for that 
> patch. So that, our further works
> on m25p80 will be reduced.
>
> [1]:  http://permalink.gmane.org/gmane.linux.drivers.mtd/48755
to Brian:
   could you please check Sourav's patch?

If you think his patch is ok, please merge it, and i can do my work base 
on his patch.

thanks
Huang Shijie



From annulen at yandex.ru  Tue Oct 22 06:10:09 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Tue, 22 Oct 2013 14:10:09 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <183031382371160@web6m.yandex.ru>
 <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>
Message-ID: <139841382436609@web24g.yandex.ru>



22.10.2013, 07:43, "Brent Taylor" <motobud at gmail.com>:
> On Mon, Oct 21, 2013 at 10:59 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>> ?04.10.2013, 07:09, "Brent Taylor" <motobud at gmail.com>:
>>> ?Here is a patch based on linux-3.12-rc3. ?I haven't performed any
>>> ?performance testing UBIFS using lz4hc, but I can mount UBIFS volumes
>>> ?and haven't seen any problems yet. ?The only think I know that isn't
>>> ?correct about the patch is the description for the Kconfig element for
>>> ?select lz4hc as a compression option. ?I only copied the description
>>> ?from the lzo description.
>> ?Hi Brent,
>>
>> ?I'm testing your patch on my SH4 device. When I create new partition
>> ?with lz4hc compressor, it works fine: I can copy file into it, and
>> ?md5sums of original and copy match. However, after reboot I cannot
>> ?read the file anymore:
>>
>> ?UBIFS error (pid 1101): ubifs_decompress: cannot decompress 934 bytes, compressor lz4hc, error -22
>> ?UBIFS error (pid 1101): read_block: bad data node (block 1, inode 65)
>> ?UBIFS error (pid 1101): do_readpage: cannot read page 1 of inode 65, error -22
>>
>> ?The same error appears if I use lz4hc-compressed ubifs image to flash rootfs
>> ?(using patched mkfs.ubifs).
>>
>> ?Decompression error occurs in lz4_uncompress() function (lib/lz4/lz4_decompress.c),
>> ?on the line 101:
>>
>> ?/* Error: offset create reference outside destination buffer */
>> ?if (unlikely(ref < (BYTE *const) dest))
>> ?????goto _output_error;
>>
>> ?Brent: are you able to read data from lz4hc volume on your device?
>> ?Anyone: any ideas what may happen here?
>>
>> ?--
>> ?Regards,
>> ?Konstantin
>
> Konstantin,
> ???I haven't seen anything like that on my at91sam9m10g45-ek
> development board. ?I haven't used a flash image from mkfs.ubifs yet.
> Is it possible the file system was not umounted cleanly before the
> reboot and UBIFS went through a recovery procedure? ?Maybe something
> breaks with lz4hc when UBIFS does a recovery? ?That's just a guess.

Could you save attached file on lz4hc volume, umount it and mount again?
I get aforementioned error when doing `cat set11.cfg`

-- 
Regards,
Konstantin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: set11.cfg
Type: application/octet-stream
Size: 169 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131022/19797e35/attachment-0001.obj>

From sk at ammonit.com  Tue Oct 22 07:52:37 2013
From: sk at ammonit.com (=?ISO-8859-1?Q?Steffen_K=FChn?=)
Date: Tue, 22 Oct 2013 13:52:37 +0200
Subject: problem with ecc errors and ubifs
Message-ID: <52666705.8040000@ammonit.com>

Hey,

my question is about ecc errors and the way ubifs deals with it.
Unfortunately, I have to be a bit detailed to make my problem clear.

We use MT29F4G08ABBDAHC flash devices from Micron. This type of flash
supports on-die-ecc (8 bit) and needs at least 4-bit-ecc. When we have
started to use this flash no support for on die ecc was available in the
kernel (kernel 3.2). The on die ecc support is - because of that - self
written.

Everything works in principle very well. But we use our hardware in
greater numbers and quite intensively. Over the months we have observed
numerous destroyed file systems with different ubi errors. For finding
the reason of that problem I have written a mechanism to create bit
errors (in U-Boot).

With that I made different tests. One test was to create only one single
bit error in the whole flash device. The on die ecc mechanism (which can
correct up to 8 bit errors) had no problems to correct this error. The
kernel code has now a piece of code where the bit error occurrence is
reported to the stages above. With this information can ubifs decide if
and what it has to do.

I have seen that such error reporting leads usually to a page "scrub". I
do not really understand what there happens. But sometimes the result is
catastrophic. Because of that I have removed the error reporting (my
hope is that 8 bit errors occur seldom enough in a page) After that code
removing our problems are completely vanished (I have even tested with
more than 8 bit errors in the same page => no problems). I could not
provoke any faults by creating numerous bit errors in dozens of pages.

What is your opinion? Have I overlooked something? I know that this
method has risks but I hope that under the line the file system stays
longer alive.

Best
Steffen



From ricard.wanderlof at axis.com  Tue Oct 22 08:05:42 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Tue, 22 Oct 2013 14:05:42 +0200
Subject: problem with ecc errors and ubifs
In-Reply-To: <52666705.8040000@ammonit.com>
References: <52666705.8040000@ammonit.com>
Message-ID: <alpine.DEB.2.00.1310221356080.28562@lnxricardw.se.axis.com>


On Tue, 22 Oct 2013, Steffen K?hn wrote:

> We use MT29F4G08ABBDAHC flash devices from Micron. This type of flash
> supports on-die-ecc (8 bit) and needs at least 4-bit-ecc. When we have
> started to use this flash no support for on die ecc was available in the
> kernel (kernel 3.2). The on die ecc support is - because of that - self
> written.
> ...
>
> I have seen that such error reporting leads usually to a page "scrub". I
> do not really understand what there happens.

I don't know the details, but scrubbing means that the data in the page 
is to be rewritten at another place in the flash, since the presence of a 
bit error indicates that the data in the page will eventually become 
unreliable.

The code as it looks today triggers scrubbing whenever a single bit 
correction is detected during read. The reason for this is that the 
classic Hamming algorithm can only handle one incorrect bit, so if another 
bit flips the data becomes unreadable.

I know there have been discussions that when using ECC that can correct 
more than a single bit in a given area, to not trigger scrubbing as soon 
as a single bit goes bad, but use a threshold mechanism, so that scrubbing 
is triggered first when, say, half the maximum amount of bits need 
correcting (e.g. in your case when 4 bits need correcting), the reason 
being that flashes which require multibit ecc tend to have bits here and 
there that flip rather quickly after writing, so triggering on them leads 
to undue scrubbing and hence wear on the flash.

> But sometimes the result is catastrophic. Because of that I have removed 
> the error reporting (my hope is that 8 bit errors occur seldom enough in 
> a page) After that code removing our problems are completely vanished (I 
> have even tested with more than 8 bit errors in the same page => no 
> problems). I could not provoke any faults by creating numerous bit 
> errors in dozens of pages.

Removing the 'corrected bit' reporting mechanism avoids scrubbing, and 
hence that code path is never executed. It seems a serious bug if the 
scrubbing mechanism doesn't work as intended, for whatever reason.

> What is your opinion? Have I overlooked something? I know that this
> method has risks but I hope that under the line the file system stays
> longer alive.

The risk would be that eventually the number of errors would grow past the 
ECC capability and subsequently lead to unreadable data. If there indeed 
is a bug in the scrubbing mechanism, I agree it would be better to just 
correct the bits and hope not too many of them flip. But it would be 
better to try and fix the problem with scrubbing...

/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 sk at ammonit.com  Tue Oct 22 09:10:39 2013
From: sk at ammonit.com (=?ISO-8859-15?Q?Steffen_K=FChn?=)
Date: Tue, 22 Oct 2013 15:10:39 +0200
Subject: problem with ecc errors and ubifs
In-Reply-To: <alpine.DEB.2.00.1310221356080.28562@lnxricardw.se.axis.com>
References: <52666705.8040000@ammonit.com>
 <alpine.DEB.2.00.1310221356080.28562@lnxricardw.se.axis.com>
Message-ID: <5266794F.8020504@ammonit.com>

Dear Ricard,

thanks for your answer.

> The risk would be that eventually the number of errors would grow past
> the ECC capability and subsequently lead to unreadable data. If there
> indeed is a bug in the scrubbing mechanism, I agree it would be better
> to just correct the bits and hope not too many of them flip. But it
> would be better to try and fix the problem with scrubbing...

I agree with you that a fix of the scrubbing mechanism would be better.
Unfortunately, the problem is very hard to reproduce (and debug).

And perhaps it is already solved? My kernel is not the newest. But it is
not possible to change the version because we have some patches (related
to other hardware) which only works with kernel 3.2.

Do you know about some important bug fixes which have something to do
with the "scrubbing" in the last months?

Best
Steffen



From caizhiyong at hisilicon.com  Tue Oct 22 09:12:44 2013
From: caizhiyong at hisilicon.com (Caizhiyong)
Date: Tue, 22 Oct 2013 13:12:44 +0000
Subject: [PATCH 1/2] block: remove unrelated header files and export symbol
In-Reply-To: <20131020120603.GA18678@localhost>
References: <C3050A4DBA34F345975765E43127F10F1C0643B8@szxeml512-mbx.china.huawei.com>
 <20131020120603.GA18678@localhost>
Message-ID: <C3050A4DBA34F345975765E43127F10F1C084C73@szxeml512-mbs.china.huawei.com>

From: CaiZhiyong <caizhiyong at huawei.com>
Subject: block: remove unrelated header files and export symbol

This patch fix up the following items:
 - remove unrelated header files.
 - export interface function.
 - modify function cmdline_parts_parse return value, this will make
   it more friendly for the caller.

Signed-off-by: CaiZhiyong <caizhiyong at huawei.com>
---
 block/cmdline-parser.c         | 18 +++++++++++-------
 include/linux/cmdline-parser.h |  8 ++++----
 2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/block/cmdline-parser.c b/block/cmdline-parser.c
index cc2637f..9dbc67e 100644
--- a/block/cmdline-parser.c
+++ b/block/cmdline-parser.c
@@ -4,8 +4,7 @@
  * Written by Cai Zhiyong <caizhiyong at huawei.com>
  *
  */
-#include <linux/buffer_head.h>
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/cmdline-parser.h>
 
 static int parse_subpart(struct cmdline_subpart **subpart, char *partdef)
@@ -159,6 +158,7 @@ void cmdline_parts_free(struct cmdline_parts **parts)
 		*parts = next_parts;
 	}
 }
+EXPORT_SYMBOL(cmdline_parts_free);
 
 int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline)
 {
@@ -206,6 +206,7 @@ fail:
 	cmdline_parts_free(parts);
 	goto done;
 }
+EXPORT_SYMBOL(cmdline_parts_parse);
 
 struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
 					 const char *bdev)
@@ -214,17 +215,17 @@ struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
 		parts = parts->next_parts;
 	return parts;
 }
+EXPORT_SYMBOL(cmdline_parts_find);
 
 /*
  *  add_part()
  *    0 success.
  *    1 can not add so many partitions.
  */
-void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
-		       int slot,
-		       int (*add_part)(int, struct cmdline_subpart *, void *),
-		       void *param)
-
+int cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
+		      int slot,
+		      int (*add_part)(int, struct cmdline_subpart *, void *),
+		      void *param)
 {
 	sector_t from = 0;
 	struct cmdline_subpart *subpart;
@@ -247,4 +248,7 @@ void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
 		if (add_part(slot, subpart, param))
 			break;
 	}
+
+	return slot;
 }
+EXPORT_SYMBOL(cmdline_parts_set);
diff --git a/include/linux/cmdline-parser.h b/include/linux/cmdline-parser.h
index 98e892e..43b65a9 100644
--- a/include/linux/cmdline-parser.h
+++ b/include/linux/cmdline-parser.h
@@ -35,9 +35,9 @@ int cmdline_parts_parse(struct cmdline_parts **parts, const char *cmdline);
 struct cmdline_parts *cmdline_parts_find(struct cmdline_parts *parts,
 					 const char *bdev);
 
-void cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
-		       int slot,
-		       int (*add_part)(int, struct cmdline_subpart *, void *),
-		       void *param);
+int cmdline_parts_set(struct cmdline_parts *parts, sector_t disk_size,
+		      int slot,
+		      int (*add_part)(int, struct cmdline_subpart *, void *),
+		      void *param);
 
 #endif /* CMDLINEPARSEH */
-- 
1.8.1.5


From caizhiyong at hisilicon.com  Tue Oct 22 09:14:17 2013
From: caizhiyong at hisilicon.com (Caizhiyong)
Date: Tue, 22 Oct 2013 13:14:17 +0000
Subject: [PATCH 2/2]  mtd: cmdlinepart: use cmdline partition parser lib
In-Reply-To: <20131020120603.GA18678@localhost>
References: <C3050A4DBA34F345975765E43127F10F1C0643B8@szxeml512-mbx.china.huawei.com>
 <20131020120603.GA18678@localhost>
Message-ID: <C3050A4DBA34F345975765E43127F10F1C084C81@szxeml512-mbs.china.huawei.com>

From: CaiZhiyong <caizhiyong at huawei.com>
Subject: mtd: cmdlinepart: use cmdline partition parser lib

In the previous version, adjust the cmdline parser code to library-style
code, and move it to a separate file "block/cmdline-parser.c", we can use
it in some client code. there is no any functionality change in the adjusting.

this patch use cmdline parser lib.

For further information, see "https://lkml.org/lkml/2013/8/6/550"

Signed-off-by: CaiZhiyong <caizhiyong at huawei.com>
---
 drivers/mtd/Kconfig       |   1 +
 drivers/mtd/cmdlinepart.c | 343 +++++-----------------------------------------
 2 files changed, 39 insertions(+), 305 deletions(-)

diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 5fab4e6e..daf544a 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -75,6 +75,7 @@ endif # MTD_REDBOOT_PARTS
 
 config MTD_CMDLINE_PARTS
 	tristate "Command line partition table parsing"
+	select BLK_CMDLINE_PARSER
 	depends on MTD
 	---help---
 	  Allow generic configuration of the MTD partition tables via the kernel
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 721caeb..ba934a4 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -47,344 +47,79 @@
  * 1 NOR Flash with 2 partitions, 1 NAND with one
  * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home)
  */
+ /*
+  * Copyright ? 2013 Cai Zhiyong <caizhiyong at huawei.com>
+  * Rewrite the cmdline parser code, adjust it to a library-style code.
+  * this module only use the cmdline parser lib.
+  */
 
 #include <linux/kernel.h>
-#include <linux/slab.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/cmdline-parser.h>
 
-/* error message prefix */
-#define ERRP "mtd: "
-
-/* debug macro */
-#if 0
-#define dbg(x) do { printk("DEBUG-CMDLINE-PART: "); printk x; } while(0)
-#else
-#define dbg(x)
-#endif
-
-
-/* special size referring to all the remaining space in a partition */
-#define SIZE_REMAINING ULLONG_MAX
-#define OFFSET_CONTINUOUS ULLONG_MAX
-
-struct cmdline_mtd_partition {
-	struct cmdline_mtd_partition *next;
-	char *mtd_id;
-	int num_parts;
-	struct mtd_partition *parts;
-};
-
-/* mtdpart_setup() parses into here */
-static struct cmdline_mtd_partition *partitions;
-
-/* the command line passed to mtdpart_setup() */
 static char *mtdparts;
-static char *cmdline;
-static int cmdline_parsed;
+static struct cmdline_parts *mtd_cmdline_parts;
 
-/*
- * Parse one partition definition for an MTD. Since there can be many
- * comma separated partition definitions, this function calls itself
- * recursively until no more partition definitions are found. Nice side
- * effect: the memory to keep the mtd_partition structs and the names
- * is allocated upon the last definition being found. At that point the
- * syntax has been verified ok.
- */
-static struct mtd_partition * newpart(char *s,
-				      char **retptr,
-				      int *num_parts,
-				      int this_part,
-				      unsigned char **extra_mem_ptr,
-				      int extra_mem_size)
+static int add_part(int slot, struct cmdline_subpart *subpart, void *param)
 {
-	struct mtd_partition *parts;
-	unsigned long long size, offset = OFFSET_CONTINUOUS;
-	char *name;
-	int name_len;
-	unsigned char *extra_mem;
-	char delim;
-	unsigned int mask_flags;
-
-	/* fetch the partition size */
-	if (*s == '-') {
-		/* assign all remaining space to this partition */
-		size = SIZE_REMAINING;
-		s++;
-	} else {
-		size = memparse(s, &s);
-		if (size < PAGE_SIZE) {
-			printk(KERN_ERR ERRP "partition size too small (%llx)\n",
-			       size);
-			return ERR_PTR(-EINVAL);
-		}
-	}
-
-	/* fetch partition name and flags */
-	mask_flags = 0; /* this is going to be a regular partition */
-	delim = 0;
-
-	/* check for offset */
-	if (*s == '@') {
-		s++;
-		offset = memparse(s, &s);
-	}
+	struct mtd_partition *mtdpart = &((struct mtd_partition *)param)[slot];
 
-	/* now look for name */
-	if (*s == '(')
-		delim = ')';
+	mtdpart->offset = subpart->from;
+	mtdpart->size = subpart->size;
+	mtdpart->name = subpart->name;
+	mtdpart->mask_flags = 0;
 
-	if (delim) {
-		char *p;
+	if (subpart->flags & PF_RDONLY)
+		mtdpart->mask_flags |= MTD_WRITEABLE;
 
-		name = ++s;
-		p = strchr(name, delim);
-		if (!p) {
-			printk(KERN_ERR ERRP "no closing %c found in partition name\n", delim);
-			return ERR_PTR(-EINVAL);
-		}
-		name_len = p - name;
-		s = p + 1;
-	} else {
-		name = NULL;
-		name_len = 13; /* Partition_000 */
-	}
-
-	/* record name length for memory allocation later */
-	extra_mem_size += name_len + 1;
-
-	/* test for options */
-	if (strncmp(s, "ro", 2) == 0) {
-		mask_flags |= MTD_WRITEABLE;
-		s += 2;
-	}
+	if (subpart->flags & PF_POWERUP_LOCK)
+		mtdpart->mask_flags |= MTD_POWERUP_LOCK;
 
-	/* if lk is found do NOT unlock the MTD partition*/
-	if (strncmp(s, "lk", 2) == 0) {
-		mask_flags |= MTD_POWERUP_LOCK;
-		s += 2;
-	}
-
-	/* test if more partitions are following */
-	if (*s == ',') {
-		if (size == SIZE_REMAINING) {
-			printk(KERN_ERR ERRP "no partitions allowed after a fill-up partition\n");
-			return ERR_PTR(-EINVAL);
-		}
-		/* more partitions follow, parse them */
-		parts = newpart(s + 1, &s, num_parts, this_part + 1,
-				&extra_mem, extra_mem_size);
-		if (IS_ERR(parts))
-			return parts;
-	} else {
-		/* this is the last partition: allocate space for all */
-		int alloc_size;
-
-		*num_parts = this_part + 1;
-		alloc_size = *num_parts * sizeof(struct mtd_partition) +
-			     extra_mem_size;
-
-		parts = kzalloc(alloc_size, GFP_KERNEL);
-		if (!parts)
-			return ERR_PTR(-ENOMEM);
-		extra_mem = (unsigned char *)(parts + *num_parts);
-	}
-
-	/* enter this partition (offset will be calculated later if it is zero at this point) */
-	parts[this_part].size = size;
-	parts[this_part].offset = offset;
-	parts[this_part].mask_flags = mask_flags;
-	if (name)
-		strlcpy(extra_mem, name, name_len + 1);
-	else
-		sprintf(extra_mem, "Partition_%03d", this_part);
-	parts[this_part].name = extra_mem;
-	extra_mem += name_len + 1;
-
-	dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n",
-	     this_part, parts[this_part].name, parts[this_part].offset,
-	     parts[this_part].size, parts[this_part].mask_flags));
-
-	/* return (updated) pointer to extra_mem memory */
-	if (extra_mem_ptr)
-		*extra_mem_ptr = extra_mem;
-
-	/* return (updated) pointer command line string */
-	*retptr = s;
-
-	/* return partition table */
-	return parts;
+	return 0;
 }
 
-/*
- * Parse the command line.
- */
-static int mtdpart_setup_real(char *s)
+static int __init mtdpart_setup(char *s)
 {
-	cmdline_parsed = 1;
-
-	for( ; s != NULL; )
-	{
-		struct cmdline_mtd_partition *this_mtd;
-		struct mtd_partition *parts;
-		int mtd_id_len, num_parts;
-		char *p, *mtd_id;
-
-		mtd_id = s;
-
-		/* fetch <mtd-id> */
-		p = strchr(s, ':');
-		if (!p) {
-			printk(KERN_ERR ERRP "no mtd-id\n");
-			return -EINVAL;
-		}
-		mtd_id_len = p - mtd_id;
-
-		dbg(("parsing <%s>\n", p+1));
-
-		/*
-		 * parse one mtd. have it reserve memory for the
-		 * struct cmdline_mtd_partition and the mtd-id string.
-		 */
-		parts = newpart(p + 1,		/* cmdline */
-				&s,		/* out: updated cmdline ptr */
-				&num_parts,	/* out: number of parts */
-				0,		/* first partition */
-				(unsigned char**)&this_mtd, /* out: extra mem */
-				mtd_id_len + 1 + sizeof(*this_mtd) +
-				sizeof(void*)-1 /*alignment*/);
-		if (IS_ERR(parts)) {
-			/*
-			 * An error occurred. We're either:
-			 * a) out of memory, or
-			 * b) in the middle of the partition spec
-			 * Either way, this mtd is hosed and we're
-			 * unlikely to succeed in parsing any more
-			 */
-			 return PTR_ERR(parts);
-		 }
-
-		/* align this_mtd */
-		this_mtd = (struct cmdline_mtd_partition *)
-				ALIGN((unsigned long)this_mtd, sizeof(void *));
-		/* enter results */
-		this_mtd->parts = parts;
-		this_mtd->num_parts = num_parts;
-		this_mtd->mtd_id = (char*)(this_mtd + 1);
-		strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
-
-		/* link into chain */
-		this_mtd->next = partitions;
-		partitions = this_mtd;
-
-		dbg(("mtdid=<%s> num_parts=<%d>\n",
-		     this_mtd->mtd_id, this_mtd->num_parts));
-
-
-		/* EOS - we're done */
-		if (*s == 0)
-			break;
-
-		/* does another spec follow? */
-		if (*s != ';') {
-			printk(KERN_ERR ERRP "bad character after partition (%c)\n", *s);
-			return -EINVAL;
-		}
-		s++;
-	}
-
-	return 0;
+	mtdparts = s;
+	return 1;
 }
+__setup("mtdparts=", mtdpart_setup);
 
-/*
- * Main function to be called from the MTD mapping driver/device to
- * obtain the partitioning information. At this point the command line
- * arguments will actually be parsed and turned to struct mtd_partition
- * information. It returns partitions for the requested mtd device, or
- * the first one in the chain if a NULL mtd_id is passed in.
- */
 static int parse_cmdline_partitions(struct mtd_info *master,
 				    struct mtd_partition **pparts,
 				    struct mtd_part_parser_data *data)
 {
-	unsigned long long offset;
-	int i, err;
-	struct cmdline_mtd_partition *part;
-	const char *mtd_id = master->name;
+	struct cmdline_parts *parts;
 
-	/* parse command line */
-	if (!cmdline_parsed) {
-		err = mtdpart_setup_real(cmdline);
-		if (err)
-			return err;
-	}
+	if (mtdparts) {
+		if (mtd_cmdline_parts)
+			cmdline_parts_free(&mtd_cmdline_parts);
 
-	/*
-	 * Search for the partition definition matching master->name.
-	 * If master->name is not set, stop at first partition definition.
-	 */
-	for (part = partitions; part; part = part->next) {
-		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))
-			break;
+		if (cmdline_parts_parse(&mtd_cmdline_parts, mtdparts)) {
+			mtdparts = NULL;
+			return -EINVAL;
+		}
+		mtdparts = NULL;
 	}
 
-	if (!part)
+	if (!mtd_cmdline_parts)
 		return 0;
 
-	for (i = 0, offset = 0; i < part->num_parts; i++) {
-		if (part->parts[i].offset == OFFSET_CONTINUOUS)
-			part->parts[i].offset = offset;
-		else
-			offset = part->parts[i].offset;
-
-		if (part->parts[i].size == SIZE_REMAINING)
-			part->parts[i].size = master->size - offset;
-
-		if (offset + part->parts[i].size > master->size) {
-			printk(KERN_WARNING ERRP
-			       "%s: partitioning exceeds flash size, truncating\n",
-			       part->mtd_id);
-			part->parts[i].size = master->size - offset;
-		}
-		offset += part->parts[i].size;
-
-		if (part->parts[i].size == 0) {
-			printk(KERN_WARNING ERRP
-			       "%s: skipping zero sized partition\n",
-			       part->mtd_id);
-			part->num_parts--;
-			memmove(&part->parts[i], &part->parts[i + 1],
-				sizeof(*part->parts) * (part->num_parts - i));
-			i--;
-		}
-	}
+	parts = cmdline_parts_find(mtd_cmdline_parts, master->name);
+	if (!parts)
+		return 0;
 
-	*pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts,
-			  GFP_KERNEL);
+	*pparts = kzalloc(sizeof(**pparts) * parts->nr_subparts, GFP_KERNEL);
 	if (!*pparts)
 		return -ENOMEM;
 
-	return part->num_parts;
+	return cmdline_parts_set(parts, master->size, 0, add_part,
+				 (void *)*pparts);
 }
 
-
-/*
- * This is the handler for our kernel parameter, called from
- * main.c::checksetup(). Note that we can not yet kmalloc() anything,
- * so we only save the commandline for later processing.
- *
- * This function needs to be visible for bootloaders.
- */
-static int __init mtdpart_setup(char *s)
-{
-	cmdline = s;
-	return 1;
-}
-
-__setup("mtdparts=", mtdpart_setup);
-
 static struct mtd_part_parser cmdline_parser = {
 	.owner = THIS_MODULE,
 	.parse_fn = parse_cmdline_partitions,
@@ -393,8 +128,6 @@ static struct mtd_part_parser cmdline_parser = {
 
 static int __init cmdline_parser_init(void)
 {
-	if (mtdparts)
-		mtdpart_setup(mtdparts);
 	return register_mtd_parser(&cmdline_parser);
 }
 
-- 
1.8.1.5


From mark.rutland at arm.com  Tue Oct 22 09:34:50 2013
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 22 Oct 2013 14:34:50 +0100
Subject: [PATCH] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382418628-4521-1-git-send-email-b32955@freescale.com>
References: <1382418628-4521-1-git-send-email-b32955@freescale.com>
Message-ID: <20131022133446.GA2766@kartoffel>

On Tue, Oct 22, 2013 at 06:10:28AM +0100, Huang Shijie wrote:
> The patch "2febcdf mtd: gpmi: set the BCHs geometry with the ecc info"
> makes the gpmi to use the ECC info provided by the MTD code, and creates
> a different NAND ecc layout for the BCH which brings a regression to us:
>    We can not mount the ubifs which was created by the old NAND ecc layout.
> 
> This patch adds a new property : "fsl,use-mtd-ecc-info".

This name sounds _extremely_ Linux-specific, and that's not the direction I'd
like to see bindings take.

> 
> If we do not enable it, we will use the ecc strength calculated by ourselves
> and use all the OOB area (this is the legacy method);
> 
> If we enable it, we will use the ecc strength provided by the MTD layer,
> and create a new NAND ecc layout which may has free space in the OOB
> (for some SLC nand, we may support the JFFS2 with the new NAND ecc layout).

If the patch you referenced changed the layout without maintainng backwards
compatibility, it sounds like it is broken and has caused a regression.

This is a work around, not a fix.

> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
>  .../devicetree/bindings/mtd/gpmi-nand.txt          |    4 ++++
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c             |    7 ++++++-
>  2 files changed, 10 insertions(+), 1 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
> index 551b2a1..fe84a3d 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
> @@ -17,6 +17,10 @@ Required properties:
>  Optional properties:
>    - nand-on-flash-bbt: boolean to enable on flash bbt option if not
>                         present false
> +  - fsl,use-mtd-ecc-info: By enabling this boolean property, the gpmi can uses
> +                       the MTD's ECC info (if the MTD has). So we may have free
> +                       space in the OOB area, and we may support the JFFS2 with
> +                       some SLC nand, such as Micron's SLC nand.

I'm not very familiar with MTDs. Where exactly does this ECC info come from? Is
it data internal to Linux, or is it probed from the device itself?

>  
>  The device tree may optionally contain sub-nodes describing partitions of the
>  address space. See partition.txt for more detail.
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 5a1bbc7..62c0712 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -271,7 +271,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
>  		dev_err(this->dev,
>  			"We can not support this nand chip."
>  			" Its required ecc strength(%d) is beyond our"
> -			" capability(%d).\n", geo->ecc_strength,
> +			" capability(%d). If you have not enabled the"
> +			"'fsl,use-mtd-ecc-info', enable it and try again.\n",
> +			geo->ecc_strength,

Why are we telling people to do that with no description as to when to do so?
Can we not just fall back to this instead?

>  			(GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX
>  					: MXS_ECC_STRENGTH_MAX));
>  		return -EINVAL;
> @@ -352,6 +354,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
>  
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> +	if (!of_property_read_bool(this->dev->of_node, "fsl,use-mtd-ecc-info"))
> +		return legacy_set_geometry(this);
> +
>  	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);

This looks like it could be reorganised to fall back if necessary.

Thanks,
Mark.


From ricard.wanderlof at axis.com  Tue Oct 22 10:10:56 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Tue, 22 Oct 2013 16:10:56 +0200
Subject: problem with ecc errors and ubifs
In-Reply-To: <5266794F.8020504@ammonit.com>
References: <52666705.8040000@ammonit.com>
 <alpine.DEB.2.00.1310221356080.28562@lnxricardw.se.axis.com>
 <5266794F.8020504@ammonit.com>
Message-ID: <alpine.DEB.2.00.1310221610040.28562@lnxricardw.se.axis.com>


On Tue, 22 Oct 2013, Steffen K?hn wrote:

> thanks for your answer.
>
>> The risk would be that eventually the number of errors would grow past
>> the ECC capability and subsequently lead to unreadable data. If there
>> indeed is a bug in the scrubbing mechanism, I agree it would be better
>> to just correct the bits and hope not too many of them flip. But it
>> would be better to try and fix the problem with scrubbing...
>
> I agree with you that a fix of the scrubbing mechanism would be better.
> Unfortunately, the problem is very hard to reproduce (and debug).

So it happens very seldom then?

> And perhaps it is already solved? My kernel is not the newest. But it is
> not possible to change the version because we have some patches (related
> to other hardware) which only works with kernel 3.2.
>
> Do you know about some important bug fixes which have something to do
> with the "scrubbing" in the last months?

Not offhand, but I don't keep track of all corrected bugs. A quick scan in 
the mailing list archives might be useful.

/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 dedekind1 at gmail.com  Tue Oct 22 10:44:24 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 22 Oct 2013 15:44:24 +0100
Subject: [PATCH] UBIFS: remove unnecessary code in ubifs_garbage_collect
In-Reply-To: <20131019132748.GC2470@localhost>
References: <OF476A1E1E.10D82F3D-ON48257BC9.002911AE-48257BC9.002A75A8@zte.com.cn>
 <20130917015105.GM4550@ld-irv-0074.broadcom.com>
 <20131019132748.GC2470@localhost>
Message-ID: <1382453064.23828.1.camel@karhu>

On Sat, 2013-10-19 at 10:27 -0300, Ezequiel Garcia wrote:
> (Ccing Artem who might have missed this one)
> 
> On Mon, Sep 16, 2013 at 06:51:05PM -0700, Brian Norris wrote:
> > On Fri, Aug 16, 2013 at 03:43:36PM +0800, wang.bo116 at zte.com.cn wrote:
> > > Hi,
> > > 	In ubifs_garbage_collect,local variable "space_before" calculate twice. In fact, at the
> > > beginning of the loop, there is no need to calculate this variable. Calculate it before call
> > > "ubifs_garbage_collect_leb" is enough. This patch just remove the unnecessary calculate code.
> > > 
> > > 
> > > 
> > > Signed-off-by: wang bo <wang.bo116 at zte.com.cn>
> > 
> > Acked-by: Brian Norris <computersforpeace at gmail.com>

Pushed to linux-ubifs.git, thanks!

-- 
Best Regards,
Artem Bityutskiy



From ricard.wanderlof at axis.com  Tue Oct 22 10:58:09 2013
From: ricard.wanderlof at axis.com (Ricard Wanderlof)
Date: Tue, 22 Oct 2013 16:58:09 +0200
Subject: How to handle ECC in erased pages?
Message-ID: <alpine.DEB.2.00.1310221610570.28562@lnxricardw.se.axis.com>


When erasing a page in a NAND flash all the bits are erased to ones so all 
bytes are 0xff . This presents a potential problem with the ECC, in that 
if the ECC for an all-ff block of data is not itself all-ff, there will be 
ECC errors when reading an erased page.

This is handled in the software Hamming and BCH cases by XOR masking the 
ECC with a bitmask such that the ECC of an erased block of data is in fact 
all-ff.

In some cases however, there are hardware NAND flash controllers with 
built-in ECC generation and management, i.e. the controller writes the ECC 
to the OOB automatically when writing a page, and automatically corrects 
potential bit errors using the ECC stored in the OOB when reading. In this 
case there is no way to influence the actual ECC bits written to the 
flash.

I've come across such a controller, which in fact does return an ECC error 
for an erased page. I'm trying to figure out a reasonable way to deal with 
this. The first step would be to verify that the page indeed is erased if 
it supposed to be, but that is compounded by the fact that bitflips could 
occur in an erased page, so that the data in fact is not all-ff when it 
should be, but should still be considered 'erased', because assuming that 
ECC were properly applied, this case would be handled transparently.

One existing case I've come across while looking through the existing NAND 
flash drivers is denali.c which when it detects an uncorrectable ECC 
error, scans the whole data and spare areas of the page for an all-ff 
condition - this would fail if there were in fact a bit flip.

davinci_nand.c uses an XOR mask for 1 bit ECC, but checks the ECC for an 
all-ff condition, deciding that the page is erased if that is the case. 
Again this ignores the problem of a bit flip in the ECC data area of an 
erased page.

fmsc_nand.c when encountering a page with more errors that the correction 
algorithm can handle (BCH-8 in this case), counts the number of 0 bits in 
the main and spare areas of the page; if the number of 0 bits is less than 
8 it considers the page erased. This would seem to be the most correct 
approach so far, but requires quite a lot of work (i.e. scanning through 
all bytes in the page) in order to accomplish this.

One thing I was considering was if when using UBI and ubifs erased blocks 
are read at all in normal operation. In fact this doesn't seem to be the 
case; once the partition has been formatted and/or mounted UBI doesn't 
need to do any scanning operations on the data. I did a quick empirical 
test by adding a printk in nand.c:nand_read_page_swecc() when an empty 
page is read, the 'reading blank page' printk was triggered during mount 
for a couple of pages (probably while reading the index pages for UBI), 
but not afterwards, until the file system started to fill up, when I 
assume some form of garbage collection was being trigged. Writing a big 
file to a new ubifs volume didn't cause any blank page printouts except 
for the ones occurring during mount.'

All in all it seems then that the performance penalty of explicitly 
checking pages that are supposedly erased would be rather small, because 
it is not done very often.

Any other thoughts on this?

/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 hch at infradead.org  Tue Oct 22 11:33:13 2013
From: hch at infradead.org (Christoph Hellwig)
Date: Tue, 22 Oct 2013 08:33:13 -0700
Subject: [PATCH, RFC] what's the point of mtd_inodefs?
Message-ID: <20131022153313.GA11923@infradead.org>

I've been looking at mtdchar as part of a bigger series touching all
kidns of places and really wonder what the point of mtd_inodefs is.

We use it to make the file->f_mapping of the mtdchar device point to
the mapping of it's inodes, but there's nothing special happening with
mtd_inodefs inodes.  It seems to me like simply switching the
backing_dev_info to the mtd one, similarly to what we do for /dev/mem
and friends would be enough for mtdchar.

If this works for the intended use case I'd love to add this series
to my to be posted series as it would simplify it greatly.


diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..a7c9f37 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -48,7 +48,6 @@ static DEFINE_MUTEX(mtd_mutex);
  */
 struct mtd_file_info {
 	struct mtd_info *mtd;
-	struct inode *ino;
 	enum mtd_file_modes mode;
 };
 
@@ -58,10 +57,6 @@ static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
 	return fixed_size_llseek(file, offset, orig, mfi->mtd->size);
 }
 
-static int count;
-static struct vfsmount *mnt;
-static struct file_system_type mtd_inodefs_type;
-
 static int mtdchar_open(struct inode *inode, struct file *file)
 {
 	int minor = iminor(inode);
@@ -69,7 +64,6 @@ static int mtdchar_open(struct inode *inode, struct file *file)
 	int ret = 0;
 	struct mtd_info *mtd;
 	struct mtd_file_info *mfi;
-	struct inode *mtd_ino;
 
 	pr_debug("MTD_open\n");
 
@@ -77,60 +71,42 @@ static int mtdchar_open(struct inode *inode, struct file *file)
 	if ((file->f_mode & FMODE_WRITE) && (minor & 1))
 		return -EACCES;
 
-	ret = simple_pin_fs(&mtd_inodefs_type, &mnt, &count);
-	if (ret)
-		return ret;
-
 	mutex_lock(&mtd_mutex);
-	mtd = get_mtd_device(NULL, devnum);
 
+	mtd = get_mtd_device(NULL, devnum);
 	if (IS_ERR(mtd)) {
 		ret = PTR_ERR(mtd);
-		goto out;
+		goto out_unlock;
 	}
 
 	if (mtd->type == MTD_ABSENT) {
 		ret = -ENODEV;
-		goto out1;
-	}
-
-	mtd_ino = iget_locked(mnt->mnt_sb, devnum);
-	if (!mtd_ino) {
-		ret = -ENOMEM;
-		goto out1;
+		goto out_put_device;
 	}
-	if (mtd_ino->i_state & I_NEW) {
-		mtd_ino->i_private = mtd;
-		mtd_ino->i_mode = S_IFCHR;
-		mtd_ino->i_data.backing_dev_info = mtd->backing_dev_info;
-		unlock_new_inode(mtd_ino);
-	}
-	file->f_mapping = mtd_ino->i_mapping;
 
 	/* You can't open it RW if it's not a writeable device */
 	if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
 		ret = -EACCES;
-		goto out2;
+		goto out_put_device;
 	}
 
 	mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
 	if (!mfi) {
 		ret = -ENOMEM;
-		goto out2;
+		goto out_put_device;
 	}
-	mfi->ino = mtd_ino;
 	mfi->mtd = mtd;
+
 	file->private_data = mfi;
+	file->f_mapping->backing_dev_info = mtd->backing_dev_info;
+
 	mutex_unlock(&mtd_mutex);
 	return 0;
 
-out2:
-	iput(mtd_ino);
-out1:
+out_put_device:
 	put_mtd_device(mtd);
-out:
+out_unlock:
 	mutex_unlock(&mtd_mutex);
-	simple_release_fs(&mnt, &count);
 	return ret;
 } /* mtdchar_open */
 
@@ -147,12 +123,9 @@ static int mtdchar_close(struct inode *inode, struct file *file)
 	if ((file->f_mode & FMODE_WRITE))
 		mtd_sync(mtd);
 
-	iput(mfi->ino);
-
 	put_mtd_device(mtd);
 	file->private_data = NULL;
 	kfree(mfi);
-	simple_release_fs(&mnt, &count);
 
 	return 0;
 } /* mtdchar_close */
@@ -1147,24 +1120,6 @@ static const struct file_operations mtd_fops = {
 #endif
 };
 
-static const struct super_operations mtd_ops = {
-	.drop_inode = generic_delete_inode,
-	.statfs = simple_statfs,
-};
-
-static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type,
-				int flags, const char *dev_name, void *data)
-{
-	return mount_pseudo(fs_type, "mtd_inode:", &mtd_ops, NULL, MTD_INODE_FS_MAGIC);
-}
-
-static struct file_system_type mtd_inodefs_type = {
-       .name = "mtd_inodefs",
-       .mount = mtd_inodefs_mount,
-       .kill_sb = kill_anon_super,
-};
-MODULE_ALIAS_FS("mtd_inodefs");
-
 int __init init_mtdchar(void)
 {
 	int ret;
@@ -1174,26 +1129,12 @@ int __init init_mtdchar(void)
 	if (ret < 0) {
 		pr_err("Can't allocate major number %d for MTD\n",
 		       MTD_CHAR_MAJOR);
-		return ret;
 	}
-
-	ret = register_filesystem(&mtd_inodefs_type);
-	if (ret) {
-		pr_err("Can't register mtd_inodefs filesystem, error %d\n",
-		       ret);
-		goto err_unregister_chdev;
-	}
-
-	return ret;
-
-err_unregister_chdev:
-	__unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
 	return ret;
 }
 
 void __exit cleanup_mtdchar(void)
 {
-	unregister_filesystem(&mtd_inodefs_type);
 	__unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
 }
 


From ivan.djelic at parrot.com  Tue Oct 22 12:10:28 2013
From: ivan.djelic at parrot.com (Ivan Djelic)
Date: Tue, 22 Oct 2013 18:10:28 +0200
Subject: How to handle ECC in erased pages?
In-Reply-To: <alpine.DEB.2.00.1310221610570.28562@lnxricardw.se.axis.com>
References: <alpine.DEB.2.00.1310221610570.28562@lnxricardw.se.axis.com>
Message-ID: <20131022161028.GA10922@parrot.com>

On Tue, Oct 22, 2013 at 04:58:09PM +0200, Ricard Wanderlof wrote:
> 
> When erasing a page in a NAND flash all the bits are erased to ones
> so all bytes are 0xff . This presents a potential problem with the
> ECC, in that if the ECC for an all-ff block of data is not itself
> all-ff, there will be ECC errors when reading an erased page.
> 
> This is handled in the software Hamming and BCH cases by XOR masking
> the ECC with a bitmask such that the ECC of an erased block of data
> is in fact all-ff.
> 
> In some cases however, there are hardware NAND flash controllers
> with built-in ECC generation and management, i.e. the controller
> writes the ECC to the OOB automatically when writing a page, and
> automatically corrects potential bit errors using the ECC stored in
> the OOB when reading. In this case there is no way to influence the
> actual ECC bits written to the flash.
> 
> I've come across such a controller, which in fact does return an ECC
> error for an erased page. I'm trying to figure out a reasonable way
> to deal with this. The first step would be to verify that the page
> indeed is erased if it supposed to be, but that is compounded by the
> fact that bitflips could occur in an erased page, so that the data
> in fact is not all-ff when it should be, but should still be
> considered 'erased', because assuming that ECC were properly
> applied, this case would be handled transparently.
> 
> One existing case I've come across while looking through the
> existing NAND flash drivers is denali.c which when it detects an
> uncorrectable ECC error, scans the whole data and spare areas of the
> page for an all-ff condition - this would fail if there were in fact
> a bit flip.
> 
> davinci_nand.c uses an XOR mask for 1 bit ECC, but checks the ECC
> for an all-ff condition, deciding that the page is erased if that is
> the case. Again this ignores the problem of a bit flip in the ECC
> data area of an erased page.
> 
> fmsc_nand.c when encountering a page with more errors that the
> correction algorithm can handle (BCH-8 in this case), counts the
> number of 0 bits in the main and spare areas of the page; if the
> number of 0 bits is less than 8 it considers the page erased. This
> would seem to be the most correct approach so far, but requires
> quite a lot of work (i.e. scanning through all bytes in the page) in
> order to accomplish this.
> 
> One thing I was considering was if when using UBI and ubifs erased
> blocks are read at all in normal operation. In fact this doesn't
> seem to be the case; once the partition has been formatted and/or
> mounted UBI doesn't need to do any scanning operations on the data.
> I did a quick empirical test by adding a printk in
> nand.c:nand_read_page_swecc() when an empty page is read, the
> 'reading blank page' printk was triggered during mount for a couple
> of pages (probably while reading the index pages for UBI), but not
> afterwards, until the file system started to fill up, when I assume
> some form of garbage collection was being trigged. Writing a big
> file to a new ubifs volume didn't cause any blank page printouts
> except for the ones occurring during mount.'
> 
> All in all it seems then that the performance penalty of explicitly
> checking pages that are supposedly erased would be rather small,
> because it is not done very often.
> 
> Any other thoughts on this?

Hi Ricard,

Here are a few additional strategies, depending on the information
provided by your hardware controller:

1. You have access to hardware-calculated ECC bytes

Upon ECC failure, you can compare calculated ECC bytes with the known
ECC sequence of an erased page. If they match, and spare ECC bytes are
all-ff (with a limited number of bitflips allowed), then you can assume
the page is erased and just ignore the ECC failure. If those conditions
are not met, you still need to check the entire erased page for bitflips.
This is quite efficient, because as you said erased pages are not read
very often, an even then, only erased pages with bitflips are checked.

2. You do not have access to hardware-calculated ECC bytes

Upon ECC failure, you need to distinguish programmed pages from erased
pages. You can do so efficently by comparing spare ECC bytes with an
all-ff sequence, allowing a limited number of bitflips. But what if an
all-ff sequence with a few bitflips happens to be a valid ECC sequence
of your hardware controller ? One possible robustness improvement is to
use one or several available spare bytes as a "programmed page" marker.
This idea is to always program those marker bytes to 0; reading back the
marker (againg with a bitflip tolerance) allows to distinguish programmed
pages from erased pages. This trick is used on some NAND devices with
on-die ECC; such devices do not attempt to correct bitflips if the marker
bytes indicate an erased page.

There are other similar tricks which you can use, depending on your hardware
controller features.
Hope this helps,
BR,
--
Ivan


From mikedunn at newsguy.com  Tue Oct 22 14:38:27 2013
From: mikedunn at newsguy.com (Mike Dunn)
Date: Tue, 22 Oct 2013 11:38:27 -0700
Subject: How to handle ECC in erased pages?
In-Reply-To: <20131022161028.GA10922@parrot.com>
References: <alpine.DEB.2.00.1310221610570.28562@lnxricardw.se.axis.com>
 <20131022161028.GA10922@parrot.com>
Message-ID: <5266C623.50404@newsguy.com>

On 10/22/2013 09:10 AM, Ivan Djelic wrote:
> On Tue, Oct 22, 2013 at 04:58:09PM +0200, Ricard Wanderlof wrote:
>>
>> When erasing a page in a NAND flash all the bits are erased to ones
>> so all bytes are 0xff . This presents a potential problem with the
>> ECC, in that if the ECC for an all-ff block of data is not itself
>> all-ff, there will be ECC errors when reading an erased page.
>>
>> This is handled in the software Hamming and BCH cases by XOR masking
>> the ECC with a bitmask such that the ECC of an erased block of data
>> is in fact all-ff.
>>
>> In some cases however, there are hardware NAND flash controllers
>> with built-in ECC generation and management, i.e. the controller
>> writes the ECC to the OOB automatically when writing a page, and
>> automatically corrects potential bit errors using the ECC stored in
>> the OOB when reading. In this case there is no way to influence the
>> actual ECC bits written to the flash.
>>
>> I've come across such a controller, which in fact does return an ECC
>> error for an erased page. I'm trying to figure out a reasonable way
>> to deal with this. The first step would be to verify that the page
>> indeed is erased if it supposed to be, but that is compounded by the
>> fact that bitflips could occur in an erased page, so that the data
>> in fact is not all-ff when it should be, but should still be
>> considered 'erased', because assuming that ECC were properly
>> applied, this case would be handled transparently.
>>
>> One existing case I've come across while looking through the
>> existing NAND flash drivers is denali.c which when it detects an
>> uncorrectable ECC error, scans the whole data and spare areas of the
>> page for an all-ff condition - this would fail if there were in fact
>> a bit flip.
>>
>> davinci_nand.c uses an XOR mask for 1 bit ECC, but checks the ECC
>> for an all-ff condition, deciding that the page is erased if that is
>> the case. Again this ignores the problem of a bit flip in the ECC
>> data area of an erased page.
>>
>> fmsc_nand.c when encountering a page with more errors that the
>> correction algorithm can handle (BCH-8 in this case), counts the
>> number of 0 bits in the main and spare areas of the page; if the
>> number of 0 bits is less than 8 it considers the page erased. This
>> would seem to be the most correct approach so far, but requires
>> quite a lot of work (i.e. scanning through all bytes in the page) in
>> order to accomplish this.
>>
>> One thing I was considering was if when using UBI and ubifs erased
>> blocks are read at all in normal operation. In fact this doesn't
>> seem to be the case; once the partition has been formatted and/or
>> mounted UBI doesn't need to do any scanning operations on the data.
>> I did a quick empirical test by adding a printk in
>> nand.c:nand_read_page_swecc() when an empty page is read, the
>> 'reading blank page' printk was triggered during mount for a couple
>> of pages (probably while reading the index pages for UBI), but not
>> afterwards, until the file system started to fill up, when I assume
>> some form of garbage collection was being trigged. Writing a big
>> file to a new ubifs volume didn't cause any blank page printouts
>> except for the ones occurring during mount.'
>>
>> All in all it seems then that the performance penalty of explicitly
>> checking pages that are supposedly erased would be rather small,
>> because it is not done very often.
>>
>> Any other thoughts on this?
> 
> Hi Ricard,
> 
> Here are a few additional strategies, depending on the information
> provided by your hardware controller:
> 
> 1. You have access to hardware-calculated ECC bytes
> 
> Upon ECC failure, you can compare calculated ECC bytes with the known
> ECC sequence of an erased page. If they match, and spare ECC bytes are
> all-ff (with a limited number of bitflips allowed), then you can assume
> the page is erased and just ignore the ECC failure. If those conditions
> are not met, you still need to check the entire erased page for bitflips.
> This is quite efficient, because as you said erased pages are not read
> very often, an even then, only erased pages with bitflips are checked.
> 
> 2. You do not have access to hardware-calculated ECC bytes
> 
> Upon ECC failure, you need to distinguish programmed pages from erased
> pages. You can do so efficently by comparing spare ECC bytes with an
> all-ff sequence, allowing a limited number of bitflips. But what if an
> all-ff sequence with a few bitflips happens to be a valid ECC sequence
> of your hardware controller ? One possible robustness improvement is to
> use one or several available spare bytes as a "programmed page" marker.
> This idea is to always program those marker bytes to 0; reading back the
> marker (againg with a bitflip tolerance) allows to distinguish programmed
> pages from erased pages. This trick is used on some NAND devices with
> on-die ECC; such devices do not attempt to correct bitflips if the marker
> bytes indicate an erased page.


FYI... The docg4 uses this strategy in the driver code, per Ivan's suggestion.
One byte in oob is reserved as the "programmed page" marker, which is set to
zero when the page is written.  The docg4 device has hardware that only
partially handles the BCH algorithm; basically error detection in hardware, but
correction in software.  The hardware generates an XOR of the ecc calculated
from the data read from the page with the ecc bytes read from oob.  When a blank
page is read error-free, the bytes generated by the hardware are a known value,
so we know that a blank page was just read.  If the hardware does not generate
this value, the marker byte is examined.  If more than half of its bits are set,
the page is assumed to be blank, but with bitflips.  The overhead of checking
all 8 bits in a byte is modest, and it only runs when bitflips have actually
ocurred.

Mike



From computersforpeace at gmail.com  Tue Oct 22 14:56:39 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 11:56:39 -0700
Subject: [PATCH] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382418628-4521-1-git-send-email-b32955@freescale.com>
References: <1382418628-4521-1-git-send-email-b32955@freescale.com>
Message-ID: <20131022185639.GK23337@ld-irv-0074.broadcom.com>

Hi Huang,

On Tue, Oct 22, 2013 at 01:10:28PM +0800, Huang Shijie wrote:
> The patch "2febcdf mtd: gpmi: set the BCHs geometry with the ecc info"
> makes the gpmi to use the ECC info provided by the MTD code, and creates
> a different NAND ecc layout for the BCH which brings a regression to us:
>    We can not mount the ubifs which was created by the old NAND ecc layout.
> 
> This patch adds a new property : "fsl,use-mtd-ecc-info".

You have a regression in your driver. You need to fix the regression
first, so we can get that into 3.12 (or at this point, more likely
-stable). This could be something like you simple diff you sent earlier.

*After* we fix the regression, we can discuss new DT bindings.

> If we do not enable it, we will use the ecc strength calculated by ourselves
> and use all the OOB area (this is the legacy method);
> 
> If we enable it, we will use the ecc strength provided by the MTD layer,
> and create a new NAND ecc layout which may has free space in the OOB
> (for some SLC nand, we may support the JFFS2 with the new NAND ecc layout).
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
>  .../devicetree/bindings/mtd/gpmi-nand.txt          |    4 ++++
>  drivers/mtd/nand/gpmi-nand/gpmi-nand.c             |    7 ++++++-
>  2 files changed, 10 insertions(+), 1 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
> index 551b2a1..fe84a3d 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
> @@ -17,6 +17,10 @@ Required properties:
>  Optional properties:
>    - nand-on-flash-bbt: boolean to enable on flash bbt option if not
>                         present false
> +  - fsl,use-mtd-ecc-info: By enabling this boolean property, the gpmi can uses
> +                       the MTD's ECC info (if the MTD has). So we may have free
> +                       space in the OOB area, and we may support the JFFS2 with
> +                       some SLC nand, such as Micron's SLC nand.

As Mark mentioned, this description is very Linux-specific. And
honestly, I don't even understand what this description means except
that I reviewed your patches and this recent regression report. It is
not self explanatory at all.

Rhetorical question: What is "the MTD's ECC info"? What am I specifying
by putting this property in the device tree?

(Answer (?): you're looking for the ECC requirements from the data
sheet, which happens to be automatically discoverable in some cases.)

... so why don't you just add a DT property to actually specify the ECC
selection itself, rather than indirectly specifying it through a vague
specification and knowledge of how your driver handles it?

Or, is the difference between your "legacy" and "new" layout more than
just the choice of ECC strength and step size? If so, then this should
be documented [1], and that well-specified difference in layout should
become part of the DT binding.

>  The device tree may optionally contain sub-nodes describing partitions of the
>  address space. See partition.txt for more detail.
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 5a1bbc7..62c0712 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -271,7 +271,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
>  		dev_err(this->dev,
>  			"We can not support this nand chip."
>  			" Its required ecc strength(%d) is beyond our"
> -			" capability(%d).\n", geo->ecc_strength,
> +			" capability(%d). If you have not enabled the"
> +			"'fsl,use-mtd-ecc-info', enable it and try again.\n",
> +			geo->ecc_strength,
>  			(GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX
>  					: MXS_ECC_STRENGTH_MAX));
>  		return -EINVAL;
> @@ -352,6 +354,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
>  
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> +	if (!of_property_read_bool(this->dev->of_node, "fsl,use-mtd-ecc-info"))
> +		return legacy_set_geometry(this);
> +
>  	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
>  }

Your first patch just needs to involve rearranging the calls to
legacy_set_geometry() and set_geometry_by_ecc_info() without any new
help from device tree.

Brian

[1] Is it somewhere in your 50-line comments in
drivers/mtd/nand/gpmi-nand/gpmi-nand.c? Perhaps this should migrate to
Documentation/


From computersforpeace at gmail.com  Tue Oct 22 16:16:24 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 13:16:24 -0700
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <1382172254-12448-5-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
Message-ID: <20131022201624.GL23337@ld-irv-0074.broadcom.com>

Hi Pekon,

On Sat, Oct 19, 2013 at 02:14:08PM +0530, Pekon Gupta wrote:
> As per comments below, NAND_CMD_RESET, NAND_CMD_READID, and NAND_CMD_PARAM would
> work only in x8 mode.
>     commit 64b37b2a63eb2f80b65c7185f0013f8ffc637ae3
>     Author:     Matthieu CASTET <matthieu.castet at parrot.com>
>     AuthorDate: 2012-11-06
>     Note that nand_scan_ident send command (NAND_CMD_RESET, NAND_CMD_READID, NAND_CMD_PARAM), address and read data
>     The ONFI specificication is not very clear for x16 device if high byte of address should be driven to 0,
>     but according to [1] it should be ok to not drive it during autodetection.
> 
>     [1]
>     3.3.2. Target Initialization
> 
>     [...]
>     The Read ID and Read Parameter Page commands only use the lower 8-bits of the data bus.
>     The host shall not issue commands that use a word data width on x16 devices until the host
>     determines the device supports a 16-bit data bus width in the parameter page.
> 
> Thus this patch run nand_scan_ident() with driver configured as x8 device.

So are you saying that the driver currently doesn't work if you started
in x16 buswidth? Are you having problems with a particular setup? What
sort of devices are you testing?

Running nand_scan_ident() with x8 when the device is actualy x16 will
just cause nand_scan_ident() to abort with an error. It doesn't help you
with the fact that RESET/READID/PARAM need special 8-bit handling on x16
devices, so you're not solving the problem alluded to by Matthieu.

> Once the NAND device is detected, and its ONFI params are read, the driver
> is re-configured based on device-width as passed by DT bindinig 'nand-bus-width'
> 
> In-case there is a mis-match between the DT binding 'nand-bus-width' and actual
> device-width detected during nand_get_flash_type() then probe returns failure.
> 
> All other low-level callback updates happen after the device detection.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>

What is your patch trying to solve? It seems like it's just a distortion
of the same code that existed previously. It tries running
nand_scan_ident() in one buswidth configuration, and then it tries the
other if it failed. You still aren't doing either of the options we
talked about previously. I'll repeat them:

(1) You specify the buswidth given by device-tree/platform-data; if this
    is incorrect, you fail

(2) You auto-configure using NAND_BUSWIDTH_AUTO, and you use that to
    validate the platform data; you just warn if the buswidth provided
    by device-tree/platform-data was incorrect

Am I sensing that you are having some implementation problem with one of
these? You really shouldn't need to run nand_scan_ident() twice.

Or perhaps the "solution" in this patch is just that you're moving
around the reassignment of the callback functions? If so, this is not
obvious... see below.

> ---
>  drivers/mtd/nand/omap2.c | 45 +++++++++++++++++++++++++++++++++------------
>  1 file changed, 33 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 5596368..d29edda 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	mtd->name		= dev_name(&pdev->dev);
>  	mtd->owner		= THIS_MODULE;
>  	nand_chip		= &info->nand;
> -	nand_chip->options	= pdata->devsize;
>  	nand_chip->options	|= NAND_SKIP_BBTSCAN;
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  	info->of_node		= pdata->of_node;
> @@ -1904,6 +1903,39 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->chip_delay = 50;
>  	}
>  
> +	/* scan NAND device connected to chip controller */

Why is this comment separated from the comment below it? Either give a
newline between them (if they're really separate) or make it a single
comment block.

> +	/* configure driver in x8 mode to read ONFI parameter page, as
> +	 * NAND_CMD_READID & NAND_CMD_PARAM may not work in x16 mode */
> +	nand_chip->options &= ~NAND_BUSWIDTH_16;
> +	if (nand_scan_ident(mtd, 1, NULL)) {
> +		/* nand_scan_ident failed */
> +		if (pdata->devsize) {
> +			/* may be because of mis-match of device-width,
> +			 * platform data (DT binding) also says its x16 device
> +			 * So re-scan with proper device-width */
> +			nand_chip->options |= pdata->devsize;
> +			if (nand_scan_ident(mtd, 1, NULL)) {
> +				err = -ENXIO;
> +				goto out_release_mem_region;
> +			}
> +		} else {
> +			/* some genuine failure, because even platform-data
> +			 * (DT binding) says that bus-width is x8 */
> +			err = -ENXIO;
> +			goto out_release_mem_region;
> +		}
> +	} else {
> +		/* nand_scan_ident passed with x8 mode */
> +		if (pdata->devsize) {
> +			/* but platform-data (DT binding) say its x16 device */
> +			pr_err("%s: incorrect bus-width config\n", DRIVER_NAME);

You only print this message in one case (detect x8, but DT said x16) and
not the other (detect x16, but DT said x8). This is a result of your
unnecessarily complicated logic here.

> +			err = -EINVAL;
> +			err = -ENXIO;
> +			goto out_release_mem_region;
> +		}
> +	}
> +
> +	/* re-populate low-level callbacks based on xfer modes */

So am I to understand that the main purpose of this patch is not about
the detection of the buswidth type, but about the (re)assignment of the
callback functions? If so, you aren't making it very clear. (I wasn't
paying too much attention to the fact that this code block is being
moved across all the callback assignments.) The above code is just a
more verbose way of doing the same thing as the code you're replacing,
with an extra check to compare with the device-tree/platform-data.

>  	switch (pdata->xfer_type) {
>  	case NAND_OMAP_PREFETCH_POLLED:
>  		nand_chip->read_buf   = omap_read_buf_pref;
> @@ -2011,17 +2043,6 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	/* DIP switches on some boards change between 8 and 16 bit
> -	 * bus widths for flash.  Try the other width if the first try fails.
> -	 */
> -	if (nand_scan_ident(mtd, 1, NULL)) {
> -		nand_chip->options ^= NAND_BUSWIDTH_16;
> -		if (nand_scan_ident(mtd, 1, NULL)) {
> -			err = -ENXIO;
> -			goto out_release_mem_region;
> -		}
> -	}
> -
>  	/* rom code layout */
>  	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
>  

Anyway, I'm just going to have to flat out NAK this patch for now.
Please rework the series without this patch and we can continue
discussion of this patch independently (for one, this thread does not
need to CC all of the device-tree folks).

Brian


From computersforpeace at gmail.com  Tue Oct 22 16:24:50 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 13:24:50 -0700
Subject: [PATCH v9 7/9] mtd: nand: omap: use drivers/mtd/nand/nand_bch.c
 wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA27C63@DBDE04.ent.ti.com>
References: <1381816197-20477-1-git-send-email-pekon@ti.com>
 <1381816197-20477-8-git-send-email-pekon@ti.com>
 <20131017022237.GC23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA27C63@DBDE04.ent.ti.com>
Message-ID: <CAN8TOE-AdHJvst5wf8X-Eo5AKu0mNU5v-p_NzpKUiPHku2uOsQ@mail.gmail.com>

On Thu, Oct 17, 2013 at 3:14 AM, Gupta, Pekon <pekon at ti.com> wrote:
>> From: Brian Norris [mailto:computersforpeace at gmail.com]
>> > On Tue, Oct 15, 2013 at 11:19:55AM +0530, Pekon Gupta wrote:
> [snip]
>
>> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
>> > index d885298..5836039 100644
>> > --- a/drivers/mtd/nand/Kconfig
>> > +++ b/drivers/mtd/nand/Kconfig
>> > @@ -96,35 +96,13 @@ config MTD_NAND_OMAP2
>> >
>> >  config MTD_NAND_OMAP_BCH
>> >     depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
>> > -   tristate "Enable support for hardware BCH error correction"
>> > +   tristate "Support hardware based BCH error correction"
>> >     default n
>> >     select BCH
>> > -   select BCH_CONST_PARAMS
>>
>> Do you know what will happen now if someone configures
>> BCH_CONST_PARAMS?
>> Would this cause problems?
>>
> As per comments in lib/bch.c
> ---------------------------
> * Option CONFIG_BCH_CONST_PARAMS can be used to force fixed values of
>  * parameters m and t; thus allowing extra compiler optimizations and providing
>  * better (up to 2x) encoding performance. Using this option makes sense when
>  * (m,t) are fixed and known in advance, e.g. when using BCH error correction
>  * on a particular NAND flash device.
> ---------------------------
> 'BCH_CONST_PARAMS' is required for optimization when BCH algorithm
> is fixed. But in omap-nand case selection of type of BCH algorithm
> (BCH4 or BCH8) comes from DT binding "ti,nand-ecc-opts".
>
> If enabled (CONFIG_BCH_CONST_PARAMS) will optimize lib/bch.c
> for BCH8 algorithm by default, so
> CASE: if BCH8 is selected by DT, then no issues
> CASE: if BCH4 is selected  then nand_bch_init() fails with following error
> + if (!info->nand.ecc.priv) {
>                 pr_err("nand: error: unable to use s/w BCH library\n");
>                 err = -EINVAL;
>                 goto out_release_mem_region;
> }

Ah, so lib/bch.c handles this gracefully enough:

#if defined(CONFIG_BCH_CONST_PARAMS)
        if ((m != (CONFIG_BCH_CONST_M)) || (t != (CONFIG_BCH_CONST_T))) {
                printk(KERN_ERR "bch encoder/decoder was configured to support "
                       "parameters m=%d, t=%d only!\n",
                       CONFIG_BCH_CONST_M, CONFIG_BCH_CONST_T);
                goto fail;
        }
#endif

>> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> [snip]
>> > -           info->bch = init_bch(nand_chip->ecc.bytes,
>> > -                                   nand_chip->ecc.strength,
>> > -                                   OMAP_ECC_BCH8_POLYNOMIAL);
>> > -           if (!info->bch) {
>> > +           info->nand.ecc.priv     = nand_bch_init(mtd,
>> > +                                           info->nand.ecc.size,
>> > +                                           info->nand.ecc.bytes,
>> > +                                           &info->nand.ecc.layout);
>>
>> Are you sure nand_bch_init() is a proper drop-in replacement for the
>> implementation you had based on init_bch()? It looks to me like they at
>> least use a differnt polynomial value (0x201b vs. 0). Is this a problem
>> for backwards compatibility?
>>
> It's not the polynomial value = 0. Rather 0x201b is selected in both cases
> Refer below code.
> ---------------
> When init_bch(m,t, 0) is called from nand_bch_init() then,
> lib/bch.c @@ init_bch(int m, int t, unsigned int prim_poly)
> (a)     /* default primitive polynomials */
>         static const unsigned int prim_poly_tab[] = {
>                 0x25, 0x43, 0x83, 0x11d, 0x211, 0x409, 0x805, 0x1053, 0x201b,
>                 0x402b, 0x8003,
>         };
> (b)     /* select a primitive polynomial for generating GF(2^m) */
>         if (prim_poly == 0)
>                 prim_poly = prim_poly_tab[m-min_m];
> (c) And, const int min_m = 5;
>
> So, for BCH8 m=13, min_m=5; So
> prim_poly = prim_poly_tab[13-5] = prim_poly_tab[8] = 0x201b
> ---------------
>
> Hence, there is no change in polynomial, it's just that instead of
> hard-coding the value, polynomial selection depends on 'm' and 't'.

I missed that. Thanks for pointing it out.

>> [...]
>>
>> A related question: do we have any current users of this driver that can
>> provide testing results for this series? Or is this work just tested
>> with new hardware?
>>
> Got a tested-by: jp.francois at cynove.com for BCH4
> But that was in May,2013 :-)
> http://lists.infradead.org/pipermail/linux-mtd/2013-May/047065.html

OK, well that's good to know. I suppose the operation of the driver
probably hasn't changed a lot in the meantime, just the DT bindings
and a few other smaller details. But we still can't call it
"Tested-by:" in its current form.

Brian


From computersforpeace at gmail.com  Tue Oct 22 16:30:09 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 13:30:09 -0700
Subject: [PATCH v10 00/10] mtd:nand:omap2: clean-up of supported ECC
 schemes
In-Reply-To: <1382172254-12448-1-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
Message-ID: <20131022203009.GM23337@ld-irv-0074.broadcom.com>

On Sat, Oct 19, 2013 at 02:14:04PM +0530, Pekon Gupta wrote:
> 
> *changes v9 -> v10*
> [PATCH 1/10], [PATCH 2/10]
>   swapped [PATCH v9 1/9] and [PATCH v9 2/9] so that DT parsing updates
>   (with backward compatibility) happen before the deprecation of DT values.
>   This way DTB does not break functionally between the patches.
> [PATCH 3/10] <no update>
> [PATCH 4/10] 
>   dropped [PATCH v9 4/9] introducing NAND_BUSWIDTH_AUTO, instead
>   using DT 'nand-bus-width' for device bus-width

As mentioned in reply to the patch, I don't think this patch belongs in
this series now, and it is still not adequate (the original code there
is wrong in some ways, but your changes are not clearly better).

> [PATCH 5/10] <no update>
> [PATCH 6/10] <no update>
> [PATCH 7/10] 
>   separated out drivers/mtd/nand/Kconfig updates into separate [PATCH v10 10/10]
>   cleanup: s/info->nand\./nand_chip->
> [PATCH 8/10] <no update>
> [PATCH 9/10] cleanup: s/out_release_mem_region/return_error
> [PATCH 10/10] <new> spawned from [PATCH v9 8/9] for Kconfig updates

Otherwise, the series looks good.

Thanks,
Brian


From computersforpeace at gmail.com  Tue Oct 22 18:03:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 15:03:54 -0700
Subject: [PATCH 1/3] mtd: plat-ram: Use module_platform_driver
In-Reply-To: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>
References: <1381466485-7534-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131022220354.GN23337@ld-irv-0074.broadcom.com>

On Fri, Oct 11, 2013 at 10:11:23AM +0530, Sachin Kamat wrote:
> module_platform_driver simplifies the code by removing boiler
> plate.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>

Pushed all 3 to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Tue Oct 22 18:05:11 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 15:05:11 -0700
Subject: [PATCH] mtd: bcm47xxpart: handle malloc failures
In-Reply-To: <1381697629-31272-1-git-send-email-hauke@hauke-m.de>
References: <1381697629-31272-1-git-send-email-hauke@hauke-m.de>
Message-ID: <20131022220511.GO23337@ld-irv-0074.broadcom.com>

On Sun, Oct 13, 2013 at 10:53:49PM +0200, Hauke Mehrtens wrote:
> Handle return NULL in malloc.
> 
> Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>

Pushed to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Tue Oct 22 18:07:41 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 15:07:41 -0700
Subject: [RESEND][PATCH V2] mtd: bcm47xxpart: detect block aligned
 Squashfs partition
In-Reply-To: <1382387677-22006-1-git-send-email-zajec5@gmail.com>
References: <1382387677-22006-1-git-send-email-zajec5@gmail.com>
Message-ID: <20131022220741.GP23337@ld-irv-0074.broadcom.com>

On Mon, Oct 21, 2013 at 10:34:37PM +0200, Rafa? Mi?ecki wrote:
> Most of the bcm47xx devices use TRX format for storing kernel and some
> partition like Squashfs or JFFS2. This is pretty flexible solution, CFE
> (the bootloader) just writes (and later boots) TRX at some hardcoded
> place and paritions can vary in the size.
> 
> However some devices don't use TRX format. Very recently we have
> discovered ZTE H218N that has kernel and rootfs partitions at some
> "random" places.
> 
> This patch allows Linux find a rootfs partition after installing custom
> image with a CFE bootloader.
> 
> Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>

Pushed to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Tue Oct 22 18:08:07 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 15:08:07 -0700
Subject: [RESEND][PATCH] mtd: bcm47xxpart: detect "factory" partition
In-Reply-To: <1382387734-22049-1-git-send-email-zajec5@gmail.com>
References: <1382387734-22049-1-git-send-email-zajec5@gmail.com>
Message-ID: <20131022220807.GQ23337@ld-irv-0074.broadcom.com>

On Mon, Oct 21, 2013 at 10:35:34PM +0200, Rafa? Mi?ecki wrote:
> A new type of partition with magic FCTY was found on Huawei E970:
> 46 43 54 59 4b 51 37 4e  41 42 31 38 41 32 39 30  |FCTYKQ7NAB18A290|
> 
> Signed-off-by: Rafa? Mi?ecki <zajec5 at gmail.com>

Pushed to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Tue Oct 22 19:33:49 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 16:33:49 -0700
Subject: [PATCH for mtd-utils 0/4] about the SLC/MLC
In-Reply-To: <1376978317-28010-1-git-send-email-b32955@freescale.com>
References: <1376978317-28010-1-git-send-email-b32955@freescale.com>
Message-ID: <20131022233349.GR23337@ld-irv-0074.broadcom.com>

On Tue, Aug 20, 2013 at 01:58:33PM +0800, Huang Shijie wrote:
> This patch set is just following the kernel changes about the SLC/MLC,
> Please see:
>   http://lists.infradead.org/pipermail/linux-mtd/2013-August/048160.html
> 
> This patch set tries to make the mtd-utils still runs in the _old_ logic
> after we changed the code in kernel.
> 
> (The maillist blocks my email for the suspicious header, so i changed the
>  title and resend it.)
> 
> 
> Huang Shijie (4):
>   add the MTD_MLCNANDFLASH case
>   mtd: mtd-abi: add a helper to detect the nand type
>   Use the mtd_type_is_nand_user() to check the nand
>   check the MLC nand type
> 
>  flash_otp_write.c     |    4 ++--
>  include/mtd/mtd-abi.h |    5 +++++
>  lib/libmtd.c          |    5 ++++-
>  lib/libmtd_legacy.c   |    3 +++
>  mtd_debug.c           |    3 +++
>  ubi-utils/mtdinfo.c   |    2 +-
>  6 files changed, 18 insertions(+), 4 deletions(-)

Pushed to mtd-utils.git. Thanks!

You're missing flash_erase.c, which still has:

	isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0;

Maybe you want a helper for struct mtd_dev_info too? Or maybe just a
helper that looks at type 'int', so it applies to both mtd_dev_info.type
and mtd_info_user.type?

Brian


From computersforpeace at gmail.com  Tue Oct 22 20:02:15 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 17:02:15 -0700
Subject: [PATCH] mtd: Move major number definitions to major.h
In-Reply-To: <1381698323-18932-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1381698323-18932-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131023000215.GS23337@ld-irv-0074.broadcom.com>

On Sun, Oct 13, 2013 at 06:05:23PM -0300, Ezequiel Garcia wrote:
> This patch moves the char and block major number definitions
> to major.h to be with the rest of the major numbers.
> While doing this, include major.h in the files that need it.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

Pushed to l2-mtd.git. Thanks!

Brian


From computersforpeace at gmail.com  Tue Oct 22 21:43:13 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 18:43:13 -0700
Subject: [PATCH]mtd: map: fixed bug in 64-bit systems
In-Reply-To: <OFED58E4A6.DD72F731-ON48257BD0.000C7F27-48257BD0.000D8AAF@zte.com.cn>
References: <20130821085758.GG31788@brian-ubuntu>
 <OFED58E4A6.DD72F731-ON48257BD0.000C7F27-48257BD0.000D8AAF@zte.com.cn>
Message-ID: <20131023014313.GT23337@ld-irv-0074.broadcom.com>

On Fri, Aug 23, 2013 at 10:24:07AM +0800, Wang Haitao wrote:
> Thanks for your advice.
> 
> Hardware?
>         CPU?XLP832,the 64-bit OS
>         NOR Flash:S29GL128S 128M
> Software:
>         Kernel:2.6.32.41
>         Filesystem:JFFS2
> 
> When writing files, errors appear:
>         Write len 182  but return retlen 180
>         Write of 182 bytes at 0x072c815c failed. returned -5, retlen 180
>         Write len 186  but return retlen 184
>         Write of 186 bytes at 0x072caff4 failed. returned -5, retlen 184
> These errors exist only in 64-bit systems,not in 32-bit systems. After
> analysis, we found that the left shift operation is wrong in
> map_word_load_partial. For instance?
>         unsigned char buf[3] ={0x9e,0x3a,0xea};
>         map_bankwidth(map) is 4;
> 
>         for (i=0; i < 3; i++) {
>                 int bitpos;
>                 bitpos = (map_bankwidth(map)-1-i)*8;
>                 orig.x[0] &= ~(0xff << bitpos);
>                 orig.x[0] |= buf[i] << bitpos;
>         }
> 
> The value of orig.x[0] is expected to be 0x9e3aeaff, but in this
> situation(64-bit System) we'll get the wrong value of 0xffffffff9e3aeaff
> due to the 64-bit sign extension:
> buf[i] is defined as "unsigned char" and the left-shift operation will
> convert it to the type of "signed int", so when left-shift buf[i] by 24
> bits, the final result will get the wrong value: 0xffffffff9e3aeaff.
> 
> If the left-shift bits are less than 24, then sign extension will not
> occur. Whereas the bankwidth of the nor flash we used is 4, therefore this
> BUG emerges.
> 
> Signed-off-by:Pang Xunlei <pang.xunlei at zte.com.cn>
> Signed-off-by: Zhang Yi <zhang.yi20 at zte.com.cn>
> Signed-off-by:Lu Zhongjun <lu.zhongjun at zte.com.cn>
> Reviewed-by: Jiang Biao <jiang.biao2 at zte.com.cn>
> Tested-by: Ma Chenggong <ma.chenggong at zte.com.cn>

Well, this still wasn't formatted correctly, but it is a good fix. I
fixed it up, added the Cc: <stable at vger.kernel.org> and applied it to
l2-mtd.git. Thanks!

Brian


From b32955 at freescale.com  Tue Oct 22 22:29:27 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 23 Oct 2013 10:29:27 +0800
Subject: [PATCH for mtd-utils 0/4] about the SLC/MLC
In-Reply-To: <20131022233349.GR23337@ld-irv-0074.broadcom.com>
References: <1376978317-28010-1-git-send-email-b32955@freescale.com>
 <20131022233349.GR23337@ld-irv-0074.broadcom.com>
Message-ID: <52673487.40908@freescale.com>

? 2013?10?23? 07:33, Brian Norris ??:
> You're missing flash_erase.c, which still has:
>
> 	isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0;
I missed it on purpose.

The "isNAND" is used for the jffs2 to write the cleanmarker.

Since the jffs2 does not support the MLC now, the above line is used to 
check the SLC nand now.
Only the SLC nand can be written with the cleanmarker.

Am i right?

thanks
Huang Shijie






From computersforpeace at gmail.com  Tue Oct 22 23:28:10 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 20:28:10 -0700
Subject: [PATCH for mtd-utils 0/4] about the SLC/MLC
In-Reply-To: <52673487.40908@freescale.com>
References: <1376978317-28010-1-git-send-email-b32955@freescale.com>
 <20131022233349.GR23337@ld-irv-0074.broadcom.com>
 <52673487.40908@freescale.com>
Message-ID: <CAN8TOE-E4sFi6239fN6gs71KTnDFMwjtTFs059+R82S0k6JBBQ@mail.gmail.com>

On Tue, Oct 22, 2013 at 7:29 PM, Huang Shijie <b32955 at freescale.com> wrote:
> ? 2013?10?23? 07:33, Brian Norris ??:
>
>> You're missing flash_erase.c, which still has:
>>
>>         isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0;
>
> I missed it on purpose.
>
> The "isNAND" is used for the jffs2 to write the cleanmarker.
>
> Since the jffs2 does not support the MLC now, the above line is used to
> check the SLC nand now.
> Only the SLC nand can be written with the cleanmarker.
>
> Am i right?

No, if you look at the code, 'isNAND' is used to help with the bad
block checking. And even for the JFFS2 stuff, all your intentional
omission does is cause MLC to be treated like NOR flash, which is
possibly even worse.

And anyway, the variable name 'isNAND' is currently misleading,
because it now only represents 'isSLC'.

Please fix 'isNAND' to reflect all NAND (SLC or MLC). If you would
like, you can add a separate check to print a nice warning or error
message if the flash is MLC and someone chose flash_erase --jffs2.

Brian


From pekon at ti.com  Wed Oct 23 01:07:48 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 23 Oct 2013 05:07:48 +0000
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20131022201624.GL23337@ld-irv-0074.broadcom.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>

Hi Brian,

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> On Sat, Oct 19, 2013 at 02:14:08PM +0530, Pekon Gupta wrote:
[...]

> >
> > Thus this patch run nand_scan_ident() with driver configured as x8 device.
> 
> So are you saying that the driver currently doesn't work if you started
> in x16 buswidth? Are you having problems with a particular setup? What
> sort of devices are you testing?
> 
No, I'm saying that you cannot read ONFI params in x16 mode.
And, that is what was pointed out in following commit log also ..
(Reference to 3.3.2. Target Initialization: given above)
So, if I run nand_scan_ident() in x16 mode, my ONFI detection would 
fail for sure ..


> Running nand_scan_ident() with x8 when the device is actualy x16 will
> just cause nand_scan_ident() to abort with an error. It doesn't help you
> with the fact that RESET/READID/PARAM need special 8-bit handling on x16
> devices, so you're not solving the problem alluded to by Matthieu.
> 
Yes, absolutely agree.. 
The original code was calling nand_scan_ident() twice, without taking
into consideration whether the first nand_scan_ident() failed because
of bus-width mismatch or something else.

I'm also calling nand_scan_ident() twice, but only when the failure may
be due to bus-width mis-match. I'm just avoiding an extra call to
nand_scan_ident() if the failure was genuine.

If the device actually was x8 then nand_scan_ident() should not fail
for the first-time (in my patch), but if it still fails, then it's a genuine failure
_not_ because of bus-width mismatch.
I'm avoiding the call to nand_scan_ident() again .. 
(same is in my comments below..)

[...]

> What is your patch trying to solve? It seems like it's just a distortion
> of the same code that existed previously. It tries running
> nand_scan_ident() in one buswidth configuration, and then it tries the
> other if it failed. You still aren't doing either of the options we
> talked about previously. I'll repeat them:
> 
Absolutely.. probably you missed my replies in [PATCH v9 4/9]...


> (1) You specify the buswidth given by device-tree/platform-data; if this
>     is incorrect, you fail
> 
Absolutely this is what I'm doing.
But tell me how would you know the actual device-width if
nand_scan_ident()  fails 
(a) to probe ONFI params and 
- your device is  not in nand_ids[]
So get the actual device width, I call the first nand_scan_ident() in x8 mode.
so that ONFI params are read.
Now, if it nand_scan_ident() fails then it means actual device *may* be x16
So, I re-invoke nand_scan_ident() with chip->option |= pdata->devsize;


> (2) You auto-configure using NAND_BUSWIDTH_AUTO, and you use that to
>     validate the platform data; you just warn if the buswidth provided
>     by device-tree/platform-data was incorrect
> 
I have removed NAND_BUSWIDTH_AUTO implementation, as per feedbacks
This is <new> patch. May be you are confusing it with earlier version...
*please re-review*


> Am I sensing that you are having some implementation problem with one of
> these? You really shouldn't need to run nand_scan_ident() twice.
> 
> Or perhaps the "solution" in this patch is just that you're moving
> around the reassignment of the callback functions? If so, this is not
> obvious... see below.
> 
I'm repost my replies from [PATCH v9 4/9] in-case you missed...

------------------------------------
The GPMC driver will be touched by NAND_BUSWIDTH_AUTO change.
There are two set of configurations in GPMC controller..
(a) device based configurations:
  These are static configurations derived on DT bindings for each
  chip-select (like NAND signal timings, etc). These done on GPMC probe.
(b) ecc-scheme based configurations:
  These are dynamic configurations done in NAND driver in
  chip->ecc.hwctl() and are refreshed at each NAND accesss.

However, 'nand-bus-width' configuration is part of both (1) and (2).
Thus, both 'OMAP NAND driver' and 'GPMC driver' need to be
consistent in programming  'nand-bus-width' otherwise ecc-engine
would not work.

Thus, I'm proceeding with (1) DT based parsing of 'nand-bus-width'.
I have re-posted [PATCH v10 4/10] with this updates. However, please
take into account that some limitation of dual programming require
such probe. New patch also call nand_scan_ident() twice, but only
on certain pre-determined conditions, not in all failure.
Once I convert to NAND_BUSWIDTH_AUTO these should get clean,
 as I would update both GPMC and NAND driver for this.
(Till then this was most optimal solution I could think of)..
------------------------------------





> > ---
> >  drivers/mtd/nand/omap2.c | 45
> +++++++++++++++++++++++++++++++++------------
> >  1 file changed, 33 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index 5596368..d29edda 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> > @@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct
> platform_device *pdev)
> >  	mtd->name		= dev_name(&pdev->dev);
> >  	mtd->owner		= THIS_MODULE;
> >  	nand_chip		= &info->nand;
> > -	nand_chip->options	= pdata->devsize;
> >  	nand_chip->options	|= NAND_SKIP_BBTSCAN;

See there is no NAND_BUSWIDTH_AUTO here ....



> > +	/* re-populate low-level callbacks based on xfer modes */
> >  	switch (pdata->xfer_type) {
> >  	case NAND_OMAP_PREFETCH_POLLED:
> >  		nand_chip->read_buf   = omap_read_buf_pref;
> 
> So am I to understand that the main purpose of this patch is not about
> the detection of the buswidth type, but about the (re)assignment of the
> callback functions? If so, you aren't making it very clear. (I wasn't
> paying too much attention to the fact that this code block is being
> moved across all the callback assignments.) The above code is just a
> more verbose way of doing the same thing as the code you're replacing,
> with an extra check to compare with the device-tree/platform-data.
> 
Nope, this is just the comment clean-up.. Please drop it if it confuses you.
One main request please review this patch by locally including it.
May be then you can understand that it has *nothing* to do with 
(re)assignment of callbacks.. rather there is no re-assignment at all
in this patch..
See there is no change in the lines below this comment change
Probably this comment clean-up confused you..


> > @@ -2011,17 +2043,6 @@ static int omap_nand_probe(struct
> platform_device *pdev)
> >  		}
> >  	}
> >
> > -	/* DIP switches on some boards change between 8 and 16 bit
> > -	 * bus widths for flash.  Try the other width if the first try fails.
> > -	 */
> > -	if (nand_scan_ident(mtd, 1, NULL)) {
> > -		nand_chip->options ^= NAND_BUSWIDTH_16;
> > -		if (nand_scan_ident(mtd, 1, NULL)) {
> > -			err = -ENXIO;
> > -			goto out_release_mem_region;
> > -		}
> > -	}
> > -
> >  	/* rom code layout */
> >  	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
> >
> 
> Anyway, I'm just going to have to flat out NAK this patch for now.
> Please rework the series without this patch and we can continue
> discussion of this patch independently (for one, this thread does not
> need to CC all of the device-tree folks).
> 

I think there was some confusion here..
So, I hv explained my patch above. Request you to please re-review this. 

I'll take NAND_BUSWIDTH_AUTO implementation as a separate patch,
because it would require changes in GPMC driver as stated above.
And so it would be all together independent patch-set.

I would wait for your reply.. 


with regards, pekon


From pekon at ti.com  Wed Oct 23 01:10:21 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 23 Oct 2013 05:10:21 +0000
Subject: [PATCH v10 00/10] mtd:nand:omap2: clean-up of supported ECC
 schemes
In-Reply-To: <20131022203009.GM23337@ld-irv-0074.broadcom.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <20131022203009.GM23337@ld-irv-0074.broadcom.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA29DCC@DBDE04.ent.ti.com>

Hi Brian,

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > [PATCH 4/10]
> >   dropped [PATCH v9 4/9] introducing NAND_BUSWIDTH_AUTO, instead
> >   using DT 'nand-bus-width' for device bus-width
> 
> As mentioned in reply to the patch, I don't think this patch belongs in
> this series now, and it is still not adequate (the original code there
> is wrong in some ways, but your changes are not clearly better).
> 
Probably there was some confusion in review this patch.. 
I have added my comments and replies to you.
Request you to please re-review..

And as I suppose this is the only remaining piece in this series, so
If that's ok, request you to please pull-in this series..
So, I can re-work on next pending series.. 


with regards, pekon


From motobud at gmail.com  Wed Oct 23 01:26:16 2013
From: motobud at gmail.com (Brent Taylor)
Date: Wed, 23 Oct 2013 00:26:16 -0500
Subject: lz4hc compression in UBIFS?
In-Reply-To: <139841382436609@web24g.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <183031382371160@web6m.yandex.ru>
 <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>
 <139841382436609@web24g.yandex.ru>
Message-ID: <CAP+RiCDVTMb6RE5kGCYSyMCF9JMpSUAM5jS4YPObkbBu=zD59g@mail.gmail.com>

Konstantin,
   I did my testing with data from /dev/urandom (which I now realize
wasn't the best choice of data source), but if I use /dev/zero (which
actually causes data compression to occur), the decompressor fails.  I
don't know the internal workings of the lz4hc compressor or the lz4
decompressor.  I couldn't find any examples of any code in the kernel
actually using the compressor.  I've cc'ed the maintainers of the
lz4hc_compress.c to see if they my have some more insight to the
issue.

-- Brent

On Tue, Oct 22, 2013 at 5:10 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 22.10.2013, 07:43, "Brent Taylor" <motobud at gmail.com>:
>> On Mon, Oct 21, 2013 at 10:59 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>>
>>>  04.10.2013, 07:09, "Brent Taylor" <motobud at gmail.com>:
>>>>  Here is a patch based on linux-3.12-rc3.  I haven't performed any
>>>>  performance testing UBIFS using lz4hc, but I can mount UBIFS volumes
>>>>  and haven't seen any problems yet.  The only think I know that isn't
>>>>  correct about the patch is the description for the Kconfig element for
>>>>  select lz4hc as a compression option.  I only copied the description
>>>>  from the lzo description.
>>>  Hi Brent,
>>>
>>>  I'm testing your patch on my SH4 device. When I create new partition
>>>  with lz4hc compressor, it works fine: I can copy file into it, and
>>>  md5sums of original and copy match. However, after reboot I cannot
>>>  read the file anymore:
>>>
>>>  UBIFS error (pid 1101): ubifs_decompress: cannot decompress 934 bytes, compressor lz4hc, error -22
>>>  UBIFS error (pid 1101): read_block: bad data node (block 1, inode 65)
>>>  UBIFS error (pid 1101): do_readpage: cannot read page 1 of inode 65, error -22
>>>
>>>  The same error appears if I use lz4hc-compressed ubifs image to flash rootfs
>>>  (using patched mkfs.ubifs).
>>>
>>>  Decompression error occurs in lz4_uncompress() function (lib/lz4/lz4_decompress.c),
>>>  on the line 101:
>>>
>>>  /* Error: offset create reference outside destination buffer */
>>>  if (unlikely(ref < (BYTE *const) dest))
>>>      goto _output_error;
>>>
>>>  Brent: are you able to read data from lz4hc volume on your device?
>>>  Anyone: any ideas what may happen here?
>>>
>>>  --
>>>  Regards,
>>>  Konstantin
>>
>> Konstantin,
>>    I haven't seen anything like that on my at91sam9m10g45-ek
>> development board.  I haven't used a flash image from mkfs.ubifs yet.
>> Is it possible the file system was not umounted cleanly before the
>> reboot and UBIFS went through a recovery procedure?  Maybe something
>> breaks with lz4hc when UBIFS does a recovery?  That's just a guess.
>
> Could you save attached file on lz4hc volume, umount it and mount again?
> I get aforementioned error when doing `cat set11.cfg`
>
> --
> Regards,
> Konstantin


From marex at denx.de  Wed Oct 23 01:33:33 2013
From: marex at denx.de (Marek Vasut)
Date: Wed, 23 Oct 2013 07:33:33 +0200
Subject: gpmi-mtd ecc regression
In-Reply-To: <52649FDA.1030804@freescale.com>
References: <CAJ+vNU1JWZp=JoBDJALh59yFybGZ0iQxMEYy8qvTFGDLhyRzqg@mail.gmail.com>
 <52649FDA.1030804@freescale.com>
Message-ID: <201310230733.33285.marex@denx.de>

Dear Huang Shijie,

> ? 2013?10?19? 01:03, Tim Harvey ??:
> > Huang,
> > 
> > The patch you made to obtain ECC info from the chip
> > (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/dr
> > ivers/mtd/nand/gpmi-nand?id=2febcdf84b75aae627c61f0a5bf531a69299966c) has
> > caused a regression for an i.MX6 board I'm working with that uses NAND
> > and ubifs.
> > 
> > I'm using a Micron MT29F8G08
> > (http://download.micron.com/pdf/datasheets/flash/nand/2_4_8gb_nand_m49a.p
> > df) which has:
> > page size: 2112 bytes (2048 + 64 bytes)
> > block size: 1056 words (1024 + 32 words)
> > plane size: 2 planes x 1024 blocks per plane
> > device size: 2Gb: 2048 blocks
> > ecc: 4bit
> > 
> > The legacy_set_geometry function comes up with:
> > gf_len=13
> > ecc_strength=8
> > page_size=2112
> > metadata_size=10
> > ecc_chunk_size=512
> > ecc_chunk_count=4
> > payload_size=2048
> > auxiliary_size=16
> > auxiliary_status_offset=12
> > block_mark_byte_offset=1999
> > 
> > and the new set_geometry_by_ecc_info comes up with:
> > gf_len=13
> > ecc_strength=4
> > page_size=2084
> > metadata_size=10
> > ecc_chunk_size=512
> > ecc_chunk_count=4
> > payload_size=2048
> > auxiliary_size=16
> > auxiliary_status_offset=12
> > block_mark_byte_offset=2018
> > block_mark_bit_offset=4
> > 
> > There are two discrepancies above:
> >   a) ecc_strength - this part has 4bit ecc but being detected as 8?
> >   b) page_size - the legacy function includes oob in page size, and the
> > 
> > new one does not
> > 
> > which is correct?
> 
> In theory, both are correct.
> 
> I am in an embarrass state now:
> [1] we can support the jffs2, when we use the set_geometry_by_ecc_info()
> to set the NAND layout.
> 
> [2] if we still use the legacy_set_geometry() to set the NAND layout, we
> can not support the jffs2 for GPMI.

It's exactly the other way around if you're talking about JFFS2 compatibility 
with the 2.6.35 FSL kernel ;-)


From richard.weinberger at gmail.com  Wed Oct 23 01:50:17 2013
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Wed, 23 Oct 2013 07:50:17 +0200
Subject: [PATCH, RFC] what's the point of mtd_inodefs?
In-Reply-To: <20131022153313.GA11923@infradead.org>
References: <20131022153313.GA11923@infradead.org>
Message-ID: <CAFLxGvwk0gbejxk6hmnu+Cw=TgXGh0=MKgSyKtm7nTVJiBBgeg@mail.gmail.com>

On Tue, Oct 22, 2013 at 5:33 PM, Christoph Hellwig <hch at infradead.org> wrote:
> I've been looking at mtdchar as part of a bigger series touching all
> kidns of places and really wonder what the point of mtd_inodefs is.

As far I can tell it was introduced because of that issue:
http://lists.infradead.org/pipermail/linux-mtd/2010-April/029593.html

> We use it to make the file->f_mapping of the mtdchar device point to
> the mapping of it's inodes, but there's nothing special happening with
> mtd_inodefs inodes.  It seems to me like simply switching the
> backing_dev_info to the mtd one, similarly to what we do for /dev/mem
> and friends would be enough for mtdchar.
>
> If this works for the intended use case I'd love to add this series
> to my to be posted series as it would simplify it greatly.
>
>
> diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> index 684bfa3..a7c9f37 100644
> --- a/drivers/mtd/mtdchar.c
> +++ b/drivers/mtd/mtdchar.c
> @@ -48,7 +48,6 @@ static DEFINE_MUTEX(mtd_mutex);
>   */
>  struct mtd_file_info {
>         struct mtd_info *mtd;
> -       struct inode *ino;
>         enum mtd_file_modes mode;
>  };
>
> @@ -58,10 +57,6 @@ static loff_t mtdchar_lseek(struct file *file, loff_t offset, int orig)
>         return fixed_size_llseek(file, offset, orig, mfi->mtd->size);
>  }
>
> -static int count;
> -static struct vfsmount *mnt;
> -static struct file_system_type mtd_inodefs_type;
> -
>  static int mtdchar_open(struct inode *inode, struct file *file)
>  {
>         int minor = iminor(inode);
> @@ -69,7 +64,6 @@ static int mtdchar_open(struct inode *inode, struct file *file)
>         int ret = 0;
>         struct mtd_info *mtd;
>         struct mtd_file_info *mfi;
> -       struct inode *mtd_ino;
>
>         pr_debug("MTD_open\n");
>
> @@ -77,60 +71,42 @@ static int mtdchar_open(struct inode *inode, struct file *file)
>         if ((file->f_mode & FMODE_WRITE) && (minor & 1))
>                 return -EACCES;
>
> -       ret = simple_pin_fs(&mtd_inodefs_type, &mnt, &count);
> -       if (ret)
> -               return ret;
> -
>         mutex_lock(&mtd_mutex);
> -       mtd = get_mtd_device(NULL, devnum);
>
> +       mtd = get_mtd_device(NULL, devnum);
>         if (IS_ERR(mtd)) {
>                 ret = PTR_ERR(mtd);
> -               goto out;
> +               goto out_unlock;
>         }
>
>         if (mtd->type == MTD_ABSENT) {
>                 ret = -ENODEV;
> -               goto out1;
> -       }
> -
> -       mtd_ino = iget_locked(mnt->mnt_sb, devnum);
> -       if (!mtd_ino) {
> -               ret = -ENOMEM;
> -               goto out1;
> +               goto out_put_device;
>         }
> -       if (mtd_ino->i_state & I_NEW) {
> -               mtd_ino->i_private = mtd;
> -               mtd_ino->i_mode = S_IFCHR;
> -               mtd_ino->i_data.backing_dev_info = mtd->backing_dev_info;
> -               unlock_new_inode(mtd_ino);
> -       }
> -       file->f_mapping = mtd_ino->i_mapping;
>
>         /* You can't open it RW if it's not a writeable device */
>         if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
>                 ret = -EACCES;
> -               goto out2;
> +               goto out_put_device;
>         }
>
>         mfi = kzalloc(sizeof(*mfi), GFP_KERNEL);
>         if (!mfi) {
>                 ret = -ENOMEM;
> -               goto out2;
> +               goto out_put_device;
>         }
> -       mfi->ino = mtd_ino;
>         mfi->mtd = mtd;
> +
>         file->private_data = mfi;
> +       file->f_mapping->backing_dev_info = mtd->backing_dev_info;
> +
>         mutex_unlock(&mtd_mutex);
>         return 0;
>
> -out2:
> -       iput(mtd_ino);
> -out1:
> +out_put_device:
>         put_mtd_device(mtd);
> -out:
> +out_unlock:
>         mutex_unlock(&mtd_mutex);
> -       simple_release_fs(&mnt, &count);
>         return ret;
>  } /* mtdchar_open */
>
> @@ -147,12 +123,9 @@ static int mtdchar_close(struct inode *inode, struct file *file)
>         if ((file->f_mode & FMODE_WRITE))
>                 mtd_sync(mtd);
>
> -       iput(mfi->ino);
> -
>         put_mtd_device(mtd);
>         file->private_data = NULL;
>         kfree(mfi);
> -       simple_release_fs(&mnt, &count);
>
>         return 0;
>  } /* mtdchar_close */
> @@ -1147,24 +1120,6 @@ static const struct file_operations mtd_fops = {
>  #endif
>  };
>
> -static const struct super_operations mtd_ops = {
> -       .drop_inode = generic_delete_inode,
> -       .statfs = simple_statfs,
> -};
> -
> -static struct dentry *mtd_inodefs_mount(struct file_system_type *fs_type,
> -                               int flags, const char *dev_name, void *data)
> -{
> -       return mount_pseudo(fs_type, "mtd_inode:", &mtd_ops, NULL, MTD_INODE_FS_MAGIC);
> -}
> -
> -static struct file_system_type mtd_inodefs_type = {
> -       .name = "mtd_inodefs",
> -       .mount = mtd_inodefs_mount,
> -       .kill_sb = kill_anon_super,
> -};
> -MODULE_ALIAS_FS("mtd_inodefs");
> -
>  int __init init_mtdchar(void)
>  {
>         int ret;
> @@ -1174,26 +1129,12 @@ int __init init_mtdchar(void)
>         if (ret < 0) {
>                 pr_err("Can't allocate major number %d for MTD\n",
>                        MTD_CHAR_MAJOR);
> -               return ret;
>         }
> -
> -       ret = register_filesystem(&mtd_inodefs_type);
> -       if (ret) {
> -               pr_err("Can't register mtd_inodefs filesystem, error %d\n",
> -                      ret);
> -               goto err_unregister_chdev;
> -       }
> -
> -       return ret;
> -
> -err_unregister_chdev:
> -       __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
>         return ret;
>  }
>
>  void __exit cleanup_mtdchar(void)
>  {
> -       unregister_filesystem(&mtd_inodefs_type);
>         __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
>  }
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



-- 
Thanks,
//richard


From computersforpeace at gmail.com  Wed Oct 23 02:13:32 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 22 Oct 2013 23:13:32 -0700
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
Message-ID: <5267690C.9080005@gmail.com>

On 10/22/2013 10:07 PM, Gupta, Pekon wrote:
>> From: Brian Norris [mailto:computersforpeace at gmail.com]
>> On Sat, Oct 19, 2013 at 02:14:08PM +0530, Pekon Gupta wrote:
> [...]
> 
>>>
>>> Thus this patch run nand_scan_ident() with driver configured as x8 device.
>>
>> So are you saying that the driver currently doesn't work if you started
>> in x16 buswidth? Are you having problems with a particular setup? What
>> sort of devices are you testing?
>>
> No, I'm saying that you cannot read ONFI params in x16 mode.
> And, that is what was pointed out in following commit log also ..
> (Reference to 3.3.2. Target Initialization: given above)
> So, if I run nand_scan_ident() in x16 mode, my ONFI detection would 
> fail for sure ..

But you cannot just run nand_scan_ident() with !(chip->options &
NAND_BUSWIDTH_16) when your devices is x16. You need to solve the ONFI
detection problem while correctly specifying NAND_BUSWIDTH_16.

Since you didn't answer the other 2 questions there: are you testing any
x16 devices?

>> Running nand_scan_ident() with x8 when the device is actualy x16 will
>> just cause nand_scan_ident() to abort with an error. It doesn't help you
>> with the fact that RESET/READID/PARAM need special 8-bit handling on x16
>> devices, so you're not solving the problem alluded to by Matthieu.
>>
> Yes, absolutely agree.. 
> The original code was calling nand_scan_ident() twice, without taking
> into consideration whether the first nand_scan_ident() failed because
> of bus-width mismatch or something else.
> 
> I'm also calling nand_scan_ident() twice, but only when the failure may
> be due to bus-width mis-match. I'm just avoiding an extra call to
> nand_scan_ident() if the failure was genuine.

You NEVER need to call nand_scan_ident() twice for the same chip.
Period. I will reject any patch that retains this pattern. It is wrong,
and I seriously doubt the code does what you think it does when you do this.

I think nand_scan_ident() may have a weak point where it won't support
ONFI properly for x16 devices. I believe NAND_BUSWIDTH_AUTO was added to
help with this fact. (I don't have any x16 devices to test it.) But if
this is a problem for you, fix it. Don't work around it.

>> What is your patch trying to solve? It seems like it's just a distortion
>> of the same code that existed previously. It tries running
>> nand_scan_ident() in one buswidth configuration, and then it tries the
>> other if it failed. You still aren't doing either of the options we
>> talked about previously. I'll repeat them:
>>
> Absolutely.. probably you missed my replies in [PATCH v9 4/9]...

No, I did not. I just don't see how you think that your code matches the
options (1) or (2) that I described. Perhaps it's a failure in
communication. I will try to be absolutely clear.

>> (1) You specify the buswidth given by device-tree/platform-data; if this
>>     is incorrect, you fail
>>
> Absolutely this is what I'm doing.

No it isn't. You are ignoring the provided buswidth information and
UNCONDITIONALLY trying x8. If/when that fails, you then error out or
retry in x16 (depending on the DT/platform-data).

This is plain wrong.

nand_base is designed (and it's documented in the comments) that the
driver must set the buswidth correctly BEFORE calling nand_scan_ident().
You may not use nand_scan_ident() as a trial-and-error identification
function.

So, to properly do (1), you should only have something like this, just
like all the other NAND drivers:

  nand_chip->options = pdata->devsize & NAND_BUSWIDTH_16;

  ret = nand_scan_ident(...);
  if (ret) {
      // exit with error code...
  }

If there is a problem with this, then you have to fix your driver or
nand_scan_ident(). Perhaps you have to adjust your readbuf() or
cmdfunc() callbacks to do this. But do not add complicated workaround
logic in your driver.

> But tell me how would you know the actual device-width if
> nand_scan_ident()  fails 

If you are not using NAND_BUSWIDTH_AUTO, then you MUST know the correct
buswidth before calling nand_scan_ident(). If your
device-tree/platform-data is wrong, then fix that.

> (a) to probe ONFI params and 
> - your device is  not in nand_ids[]
> So get the actual device width, I call the first nand_scan_ident() in x8 mode.
> so that ONFI params are read.

You don't call nand_scan_ident() with !(chip->options &
NAND_BUSWIDTH_16) when you have an x16 device.

Now, if this causes NAND_CMD_PARAM to fail, then you have a *different*
problem to solve. But you are not solving this problem.

[snipping the rest]

I read your patch, and I gave you my review. I will not accept this
patch, nor any patch that works around nand_scan_ident() by calling it
twice. Fix the framework if the framework is giving you problems.

I believe that this patch is not integral to the rest of the series, so
I will repeat: separate this patch out so I can take the rest of this
series without it.

Brian


From annulen at yandex.ru  Wed Oct 23 03:40:34 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Wed, 23 Oct 2013 11:40:34 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <CAP+RiCDVTMb6RE5kGCYSyMCF9JMpSUAM5jS4YPObkbBu=zD59g@mail.gmail.com>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <183031382371160@web6m.yandex.ru>
 <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>
 <139841382436609@web24g.yandex.ru>
 <CAP+RiCDVTMb6RE5kGCYSyMCF9JMpSUAM5jS4YPObkbBu=zD59g@mail.gmail.com>
Message-ID: <300471382514034@web11h.yandex.ru>



23.10.2013, 09:26, "Brent Taylor" <motobud at gmail.com>:
> Konstantin,
> ???I did my testing with data from /dev/urandom (which I now realize
> wasn't the best choice of data source), but if I use /dev/zero (which
> actually causes data compression to occur), the decompressor fails. ?I
> don't know the internal workings of the lz4hc compressor or the lz4
> decompressor. ?I couldn't find any examples of any code in the kernel
> actually using the compressor. ?I've cc'ed the maintainers of the
> lz4hc_compress.c to see if they my have some more insight to the
> issue.

Does decompressor fail for you with the same error messages?

Have you tried to copy my file to the volume? It looks like minimal test case
for my board, if I remove any line decompressor works fine.

-- 
Regards,
Konstantin


From hch at infradead.org  Wed Oct 23 06:03:03 2013
From: hch at infradead.org (Christoph Hellwig)
Date: Wed, 23 Oct 2013 03:03:03 -0700
Subject: [PATCH, RFC] what's the point of mtd_inodefs?
In-Reply-To: <CAFLxGvwk0gbejxk6hmnu+Cw=TgXGh0=MKgSyKtm7nTVJiBBgeg@mail.gmail.com>
References: <20131022153313.GA11923@infradead.org>
 <CAFLxGvwk0gbejxk6hmnu+Cw=TgXGh0=MKgSyKtm7nTVJiBBgeg@mail.gmail.com>
Message-ID: <20131023100303.GA20373@infradead.org>

On Wed, Oct 23, 2013 at 07:50:17AM +0200, Richard Weinberger wrote:
> On Tue, Oct 22, 2013 at 5:33 PM, Christoph Hellwig <hch at infradead.org> wrote:
> > I've been looking at mtdchar as part of a bigger series touching all
> > kidns of places and really wonder what the point of mtd_inodefs is.
> 
> As far I can tell it was introduced because of that issue:
> http://lists.infradead.org/pipermail/linux-mtd/2010-April/029593.html

Not sure how that issue came up as writeback only ever uses
mapping->backing_dev_info for block devices, else it only uses s_bdi to
avoid this issue.  As pointed out somewhere in that thread the mem
driver uses a similar scheme.



From jason at lakedaemon.net  Wed Oct 23 07:28:23 2013
From: jason at lakedaemon.net (Jason Cooper)
Date: Wed, 23 Oct 2013 07:28:23 -0400
Subject: [PATCH v2 01/27] clk: mvebu: Add Core Divider clock
In-Reply-To: <1382137374-21251-2-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382137374-21251-2-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131023112823.GF24520@titan.lakedaemon.net>

Ezequiel,

MikeT took this the other day.

As such, I've taken in patches 2-4 inclusive into mvebu/dt.  That should
be the last items for this window.

Please drop them from your series next time around.

thx,

Jason.

On Fri, Oct 18, 2013 at 08:02:28PM -0300, Ezequiel Garcia wrote:
> This commit introduces a new group of clocks present in Armada 370/XP
> SoCs (called "Core Divider" clocks) and add a provider for them.
> The only clock supported for now is the NAND clock (ndclk), but the
> infrastructure to add the rest is already set.
> 
> Reviewed-by: Gregory CLEMENT <gregory.clement at free-electrons.com>
> Acked-by: Jason Cooper <jason at lakedaemon.net>
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/clk/mvebu/Kconfig       |   5 +
>  drivers/clk/mvebu/Makefile      |   1 +
>  drivers/clk/mvebu/clk-corediv.c | 223 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 229 insertions(+)
>  create mode 100644 drivers/clk/mvebu/clk-corediv.c
> 
> diff --git a/drivers/clk/mvebu/Kconfig b/drivers/clk/mvebu/Kconfig
> index 0b0f3e7..c339b82 100644
> --- a/drivers/clk/mvebu/Kconfig
> +++ b/drivers/clk/mvebu/Kconfig
> @@ -4,15 +4,20 @@ config MVEBU_CLK_COMMON
>  config MVEBU_CLK_CPU
>  	bool
>  
> +config MVEBU_CLK_COREDIV
> +	bool
> +
>  config ARMADA_370_CLK
>  	bool
>  	select MVEBU_CLK_COMMON
>  	select MVEBU_CLK_CPU
> +	select MVEBU_CLK_COREDIV
>  
>  config ARMADA_XP_CLK
>  	bool
>  	select MVEBU_CLK_COMMON
>  	select MVEBU_CLK_CPU
> +	select MVEBU_CLK_COREDIV
>  
>  config DOVE_CLK
>  	bool
> diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile
> index 1c7e70c..21bbfb4 100644
> --- a/drivers/clk/mvebu/Makefile
> +++ b/drivers/clk/mvebu/Makefile
> @@ -1,5 +1,6 @@
>  obj-$(CONFIG_MVEBU_CLK_COMMON)	+= common.o
>  obj-$(CONFIG_MVEBU_CLK_CPU) 	+= clk-cpu.o
> +obj-$(CONFIG_MVEBU_CLK_COREDIV)	+= clk-corediv.o
>  
>  obj-$(CONFIG_ARMADA_370_CLK)	+= armada-370.o
>  obj-$(CONFIG_ARMADA_XP_CLK)	+= armada-xp.o
> diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c
> new file mode 100644
> index 0000000..7162615
> --- /dev/null
> +++ b/drivers/clk/mvebu/clk-corediv.c
> @@ -0,0 +1,223 @@
> +/*
> + * MVEBU Core divider clock
> + *
> + * Copyright (C) 2013 Marvell
> + *
> + * Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2.  This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include "common.h"
> +
> +#define CORE_CLK_DIV_RATIO_MASK		0xff
> +#define CORE_CLK_DIV_RATIO_RELOAD	BIT(8)
> +#define CORE_CLK_DIV_ENABLE_OFFSET	24
> +#define CORE_CLK_DIV_RATIO_OFFSET	0x8
> +
> +struct clk_corediv_desc {
> +	unsigned int mask;
> +	unsigned int offset;
> +	unsigned int fieldbit;
> +};
> +
> +struct clk_corediv {
> +	struct clk_hw hw;
> +	void __iomem *reg;
> +	struct clk_corediv_desc desc;
> +	spinlock_t lock;
> +};
> +
> +static struct clk_onecell_data clk_data;
> +
> +static const struct clk_corediv_desc mvebu_corediv_desc[] __initconst = {
> +	{ .mask = 0x3f, .offset = 8, .fieldbit = 1 }, /* NAND clock */
> +};
> +
> +#define to_corediv_clk(p) container_of(p, struct clk_corediv, hw)
> +
> +static int clk_corediv_is_enabled(struct clk_hw *hwclk)
> +{
> +	struct clk_corediv *corediv = to_corediv_clk(hwclk);
> +	struct clk_corediv_desc *desc = &corediv->desc;
> +	u32 enable_mask = BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET;
> +
> +	return !!(readl(corediv->reg) & enable_mask);
> +}
> +
> +static int clk_corediv_enable(struct clk_hw *hwclk)
> +{
> +	struct clk_corediv *corediv = to_corediv_clk(hwclk);
> +	struct clk_corediv_desc *desc = &corediv->desc;
> +	unsigned long flags = 0;
> +	u32 reg;
> +
> +	spin_lock_irqsave(&corediv->lock, flags);
> +
> +	reg = readl(corediv->reg);
> +	reg |= (BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
> +	writel(reg, corediv->reg);
> +
> +	spin_unlock_irqrestore(&corediv->lock, flags);
> +
> +	return 0;
> +}
> +
> +static void clk_corediv_disable(struct clk_hw *hwclk)
> +{
> +	struct clk_corediv *corediv = to_corediv_clk(hwclk);
> +	struct clk_corediv_desc *desc = &corediv->desc;
> +	unsigned long flags = 0;
> +	u32 reg;
> +
> +	spin_lock_irqsave(&corediv->lock, flags);
> +
> +	reg = readl(corediv->reg);
> +	reg &= ~(BIT(desc->fieldbit) << CORE_CLK_DIV_ENABLE_OFFSET);
> +	writel(reg, corediv->reg);
> +
> +	spin_unlock_irqrestore(&corediv->lock, flags);
> +}
> +
> +static unsigned long clk_corediv_recalc_rate(struct clk_hw *hwclk,
> +					 unsigned long parent_rate)
> +{
> +	struct clk_corediv *corediv = to_corediv_clk(hwclk);
> +	struct clk_corediv_desc *desc = &corediv->desc;
> +	u32 reg, div;
> +
> +	reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
> +	div = (reg >> desc->offset) & desc->mask;
> +	return parent_rate / div;
> +}
> +
> +static long clk_corediv_round_rate(struct clk_hw *hwclk, unsigned long rate,
> +			       unsigned long *parent_rate)
> +{
> +	/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */
> +	u32 div;
> +
> +	div = *parent_rate / rate;
> +	if (div < 4)
> +		div = 4;
> +	else if (div > 6)
> +		div = 8;
> +
> +	return *parent_rate / div;
> +}
> +
> +static int clk_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,
> +			    unsigned long parent_rate)
> +{
> +	struct clk_corediv *corediv = to_corediv_clk(hwclk);
> +	struct clk_corediv_desc *desc = &corediv->desc;
> +	unsigned long flags = 0;
> +	u32 reg, div;
> +
> +	div = parent_rate / rate;
> +
> +	spin_lock_irqsave(&corediv->lock, flags);
> +
> +	/* Write new divider to the divider ratio register */
> +	reg = readl(corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
> +	reg &= ~(desc->mask << desc->offset);
> +	reg |= (div & desc->mask) << desc->offset;
> +	writel(reg, corediv->reg + CORE_CLK_DIV_RATIO_OFFSET);
> +
> +	/* Set reload-force for this clock */
> +	reg = readl(corediv->reg) | BIT(desc->fieldbit);
> +	writel(reg, corediv->reg);
> +
> +	/* Now trigger the clock update */
> +	reg = readl(corediv->reg) | CORE_CLK_DIV_RATIO_RELOAD;
> +	writel(reg, corediv->reg);
> +
> +	/*
> +	 * Wait for clocks to settle down, and then clear all the
> +	 * ratios request and the reload request.
> +	 */
> +	udelay(1000);
> +	reg &= ~(CORE_CLK_DIV_RATIO_MASK | CORE_CLK_DIV_RATIO_RELOAD);
> +	writel(reg, corediv->reg);
> +	udelay(1000);
> +
> +	spin_unlock_irqrestore(&corediv->lock, flags);
> +
> +	return 0;
> +}
> +
> +static const struct clk_ops corediv_ops = {
> +	.enable = clk_corediv_enable,
> +	.disable = clk_corediv_disable,
> +	.is_enabled = clk_corediv_is_enabled,
> +	.recalc_rate = clk_corediv_recalc_rate,
> +	.round_rate = clk_corediv_round_rate,
> +	.set_rate = clk_corediv_set_rate,
> +};
> +
> +static void __init mvebu_corediv_clk_init(struct device_node *node)
> +{
> +	struct clk_init_data init;
> +	struct clk_corediv *corediv;
> +	struct clk **clks;
> +	void __iomem *base;
> +	const char *parent_name;
> +	const char *clk_name;
> +	int i;
> +
> +	base = of_iomap(node, 0);
> +	if (WARN_ON(!base))
> +		return;
> +
> +	parent_name = of_clk_get_parent_name(node, 0);
> +
> +	clk_data.clk_num = ARRAY_SIZE(mvebu_corediv_desc);
> +
> +	/* clks holds the clock array */
> +	clks = kcalloc(clk_data.clk_num, sizeof(struct clk *),
> +				GFP_KERNEL);
> +	if (WARN_ON(!clks))
> +		goto err_unmap;
> +	/* corediv holds the clock specific array */
> +	corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),
> +				GFP_KERNEL);
> +	if (WARN_ON(!corediv))
> +		goto err_free_clks;
> +
> +	spin_lock_init(&corediv->lock);
> +
> +	for (i = 0; i < clk_data.clk_num; i++) {
> +		of_property_read_string_index(node, "clock-output-names",
> +					      i, &clk_name);
> +		init.num_parents = 1;
> +		init.parent_names = &parent_name;
> +		init.name = clk_name;
> +		init.ops = &corediv_ops;
> +		init.flags = 0;
> +
> +		corediv[i].desc = mvebu_corediv_desc[i];
> +		corediv[i].reg = base;
> +		corediv[i].hw.init = &init;
> +
> +		clks[i] = clk_register(NULL, &corediv[i].hw);
> +		WARN_ON(IS_ERR(clks[i]));
> +	}
> +
> +	clk_data.clks = clks;
> +	of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
> +	return;
> +
> +err_free_clks:
> +	kfree(clks);
> +err_unmap:
> +	iounmap(base);
> +}
> +CLK_OF_DECLARE(mvebu_corediv_clk, "marvell,armada-370-corediv-clock",
> +	       mvebu_corediv_clk_init);
> -- 
> 1.8.1.5
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From pekon at ti.com  Wed Oct 23 08:30:16 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 23 Oct 2013 12:30:16 +0000
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <5267690C.9080005@gmail.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2A049@DBDE04.ent.ti.com>

Hi Brian,

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On 10/22/2013 10:07 PM, Gupta, Pekon wrote:
> >> From: Brian Norris [mailto:computersforpeace at gmail.com]
> >> On Sat, Oct 19, 2013 at 02:14:08PM +0530, Pekon Gupta wrote:

[...]

>> So are you saying that the driver currently doesn't work if you started
>> in x16 buswidth? Are you having problems with a particular setup? What
>> sort of devices are you testing?
>>
...
> Since you didn't answer the other 2 questions there: are you testing any
> x16 devices?
> 

Ans-1: Yes, I'm testing on following boards:
  (a) AM335x-EVM which has x8 Micron device.
  http://www.ti.com/tool/tmdxevm3358
  (b) beaglebone with 'NAND cape', which has x16 Micron device.
  http://beagleboardtoys.info/index.php?title=BeagleBone_4Gb_16-Bit_NAND_Module
  (c) AM437x board (which has 4K page NAND from Macronix).
  (d) Also would be testing on DRA7xx again having Micron Device.

Ans-2:
Its not the setup but rather constrain in nand_base.c which prevents
reading of ONFI params in x16 mode. Please read below..

Ans-3:
Mostly are either x8 or x16 SLC NAND device.


[...]

> You NEVER need to call nand_scan_ident() twice for the same chip.
> Period. I will reject any patch that retains this pattern. It is wrong,
> and I seriously doubt the code does what you think it does when you do this.
> 
> I think nand_scan_ident() may have a weak point where it won't support
> ONFI properly for x16 devices. I believe NAND_BUSWIDTH_AUTO was added
> to
> help with this fact. (I don't have any x16 devices to test it.) But if
> this is a problem for you, fix it. Don't work around it.
> 
So, here comes the conflict.. 
If I'm _not_ using NAND_BUSWIDTH_AUTO, how should I read the ONFI 
params on x16 device ? I don't think there is any way because of following
code in generic nand_base.c
@@ nand_flash_onfi_detect()
/*
 * ONFI must be probed in 8-bit mode or with NAND_BUSWIDTH_AUTO, not
 * with NAND_BUSWIDTH_16
 */
if (chip->options & NAND_BUSWIDTH_16) {
	pr_err("ONFI cannot be probed in 16-bit mode; aborting\n");
	return 0;
}

Introduced in commit..
commit 0ce82b7f7b7373b16ecf7b5725e21e2975204500
Author:     Matthieu CASTET <matthieu.castet at parrot.com>
AuthorDate: 2013-01-16

And, I think this commit has implicitly made NAND_BUSWIDTH_AUTO
*mandatory* to be supported by every driver for interfacing with
x16 NAND devices. Isn't it ?
(unless you add every x16 device present in market to nand_flash_id[])

 [...]

> nand_base is designed (and it's documented in the comments) that the
> driver must set the buswidth correctly BEFORE calling nand_scan_ident().
> You may not use nand_scan_ident() as a trial-and-error identification
> function.
> 
> So, to properly do (1), you should only have something like this, just
> like all the other NAND drivers:
> 
>   nand_chip->options = pdata->devsize & NAND_BUSWIDTH_16;
> 
>   ret = nand_scan_ident(...);
>   if (ret) {
>       // exit with error code...
>   }
> 
For a x16 device.. This would *always* fail for x16 device, unless device
is listed in nand_flash_id[]. isn't  it ?
because you cannot read ONFI params in x16 mode, and your device is
not listed in nand_flash_ids[], so your device would not get identified.

And I sincerely don't know how other NAND drivers are probing
x16 NAND devices _without_ enabling NAND_BUSWIDTH_AUTO.
(may be by adding every supported NAND device to nand_flash_id[]
look-up table, which is not recommended).


> If there is a problem with this, then you have to fix your driver or
> nand_scan_ident(). Perhaps you have to adjust your readbuf() or
> cmdfunc() callbacks to do this. But do not add complicated workaround
> logic in your driver.
> 
chip->cmdfunc() and chip->readbufs() are all fine. Rather I let the
generic driver set them for nand_scan_ident().
So, all this calling nand_scan_ident() twice was done because of
previously mentioned reasons..


> [snipping the rest]
> 
> I read your patch, and I gave you my review. I will not accept this
> patch, nor any patch that works around nand_scan_ident() by calling it
> twice. Fix the framework if the framework is giving you problems.
> 
It's a chicken and egg problem, 
I have no solution but all I can say is the above commit, which converted
WARNING into ERROR, until all drivers adapt to NAND_BUSWIDTH_AUTO.

Anyway I have to do nand_scan_ident() somewhere before populating
the chip->ecc.layout and other fields.. so can't drop the patch..
But I'll put your suggestion, instead of my mine.

> I believe that this patch is not integral to the rest of the series, so
> I will repeat: separate this patch out so I can take the rest of this
> series without it.
> 
I'll replace the patch with your suggestions,
So, that you have both versions. Please pick whichever you like :-)


with regards, pekon


From ezequiel.garcia at free-electrons.com  Wed Oct 23 08:55:17 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 23 Oct 2013 09:55:17 -0300
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <5267690C.9080005@gmail.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com>
Message-ID: <20131023125516.GA2458@localhost>

Brian,

On Tue, Oct 22, 2013 at 11:13:32PM -0700, Brian Norris wrote:
> On 10/22/2013 10:07 PM, Gupta, Pekon wrote:
> >> From: Brian Norris [mailto:computersforpeace at gmail.com]
> >> On Sat, Oct 19, 2013 at 02:14:08PM +0530, Pekon Gupta wrote:
> > [...]
> > 
> >>>
> >>> Thus this patch run nand_scan_ident() with driver configured as x8 device.
> >>
> >> So are you saying that the driver currently doesn't work if you started
> >> in x16 buswidth? Are you having problems with a particular setup? What
> >> sort of devices are you testing?
> >>
> > No, I'm saying that you cannot read ONFI params in x16 mode.
> > And, that is what was pointed out in following commit log also ..
> > (Reference to 3.3.2. Target Initialization: given above)
> > So, if I run nand_scan_ident() in x16 mode, my ONFI detection would 
> > fail for sure ..
> 
> But you cannot just run nand_scan_ident() with !(chip->options &
> NAND_BUSWIDTH_16) when your devices is x16. You need to solve the ONFI
> detection problem while correctly specifying NAND_BUSWIDTH_16.
> 
> Since you didn't answer the other 2 questions there: are you testing any
> x16 devices?
> 

I'm jumping on this thread without having read all the discussion, sorry
about that.

FWIW, I have a Beaglebone with a 16-bit bus NAND attached to it.

Coincidentally, yesterday I was doing some tests as I'm ramping up the
NAND and I found that weird double nand_scan_ident() call.
The whole thing looks buggy to me, so I'm happy to help, review, test
and patches to take care of this.

I'm using some TI SDK with some ancient v3.2.x (with no git history!),
but from this discussion it seems the issue is still present in
mainline.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From motobud at gmail.com  Wed Oct 23 08:49:24 2013
From: motobud at gmail.com (Brent Taylor)
Date: Wed, 23 Oct 2013 07:49:24 -0500
Subject: lz4hc compression in UBIFS?
In-Reply-To: <300471382514034@web11h.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <183031382371160@web6m.yandex.ru>
 <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>
 <139841382436609@web24g.yandex.ru>
 <CAP+RiCDVTMb6RE5kGCYSyMCF9JMpSUAM5jS4YPObkbBu=zD59g@mail.gmail.com>
 <300471382514034@web11h.yandex.ru>
Message-ID: <CAP+RiCBSPAHc2aM9byRjhFVePRU-1ODL9aJvN2Y65S4Ddj4sDA@mail.gmail.com>

On Wed, Oct 23, 2013 at 2:40 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>
> 23.10.2013, 09:26, "Brent Taylor" <motobud at gmail.com>:
>> Konstantin,
>>    I did my testing with data from /dev/urandom (which I now realize
>> wasn't the best choice of data source), but if I use /dev/zero (which
>> actually causes data compression to occur), the decompressor fails.  I
>> don't know the internal workings of the lz4hc compressor or the lz4
>> decompressor.  I couldn't find any examples of any code in the kernel
>> actually using the compressor.  I've cc'ed the maintainers of the
>> lz4hc_compress.c to see if they my have some more insight to the
>> issue.
>
> Does decompressor fail for you with the same error messages?
>
> Have you tried to copy my file to the volume? It looks like minimal test case
> for my board, if I remove any line decompressor works fine.
>
> --
> Regards,
> Konstantin

Yes, I get the same error, here's a dump from UBIFS when I cat a file
filled with data from /dev/zero:

UBIFS error (pid 4288): ubifs_decompress: cannot decompress 12 bytes,
compressor lz4hc, error -22
UBIFS error (pid 4288): read_block: bad data node (block 0, inode 71)
        magic          0x6101831
        crc            0xff61a078
        node_type      1 (data node)
        group_type     0 (no node group)
        sqnum          2700
        len            60
        key            (71, data, 0)
        size           512
        compr_typ      3
        data size      12
        data:
        00000000: 1f 00 01 00 ff e8 50 00 00 00 00 00
UBIFS error (pid 4288): do_readpage: cannot read page 0 of inode 71, error -22
cat: /opt/data/zero.bin: Input/output error

Steps to reproduce are:
1.  Create a file with all zeros: dd if=/dev/zero bs=512 count=1
of=/opt/data/zero.bin
2.  Unmount ubifs and detach ubi partition
3.  attach ubi partition and mount ubifs
4. cat /opt/data/zero.bin


From ezequiel.garcia at free-electrons.com  Wed Oct 23 09:06:51 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 23 Oct 2013 10:06:51 -0300
Subject: [PATCH v2 01/27] clk: mvebu: Add Core Divider clock
In-Reply-To: <20131023112823.GF24520@titan.lakedaemon.net>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382137374-21251-2-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131023112823.GF24520@titan.lakedaemon.net>
Message-ID: <20131023130650.GB2458@localhost>

Jason,

On Wed, Oct 23, 2013 at 07:28:23AM -0400, Jason Cooper wrote:
> Ezequiel,
> 
> MikeT took this the other day.
> 
> As such, I've taken in patches 2-4 inclusive into mvebu/dt.  That should
> be the last items for this window.
> 

Just saw the pull... thanks a lot!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Wed Oct 23 09:15:20 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 23 Oct 2013 13:15:20 +0000
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20131023125516.GA2458@localhost>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com> <20131023125516.GA2458@localhost>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2A0CB@DBDE04.ent.ti.com>

Hi,

> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
[...]
> FWIW, I have a Beaglebone with a 16-bit bus NAND attached to it.
> 
> Coincidentally, yesterday I was doing some tests as I'm ramping up the
> NAND and I found that weird double nand_scan_ident() call.
> The whole thing looks buggy to me, so I'm happy to help, review, test
> and patches to take care of this.
> 
Yes, thanks .. that would be of great help.. 
And may be your experience of Atmel drivers would help me here..

*Correct, should not be double calls to nand_scan_ident()..*
But there is a constrain in nand_base.c, that it does not allow ONFI
page reading in x16 mode.. So how to overcome that..

I see the similar implementation in your ATMEL driver, it does not use
NAND_BUSWIDTH_AUTO so how do you perform ONFI read
for x16 devices ?
drivers/mtd/nand/atmel_nand.c @@atmel_nand_probe()
/* here you move to x16 mode based on your DT or platform data */
	if (host->board.bus_width_16)	/* 16-bit bus width */
		nand_chip->options |= NAND_BUSWIDTH_16;
/* And then you call nand_scan_ident */
/* first scan to find the device and get the page size */
	if (nand_scan_ident(mtd, 1, NULL)) {
		res = -ENXIO;
		goto err_scan_ident;
	}

Wouldn't this fail, _unless_ your device is listed in nand_flash_id[] ?
because it would not be able to read ONFI params.. 
Refer below commit.. 
commit 0ce82b7f7b7373b16ecf7b5725e21e2975204500
Author:     Matthieu CASTET <matthieu.castet at parrot.com>
AuthorDate: 2013-01-16

Thanks for pitching in, this would help me to understand this better.



> I'm using some TI SDK with some ancient v3.2.x (with no git history!),
> but from this discussion it seems the issue is still present in
> mainline.
> 
Aah sorry, then you might have some problem here in rebasing the
patches. But still if you can, thanks much ..


with regards, pekon

From ezequiel.garcia at free-electrons.com  Wed Oct 23 09:24:58 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 23 Oct 2013 10:24:58 -0300
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2A0CB@DBDE04.ent.ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com> <20131023125516.GA2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A0CB@DBDE04.ent.ti.com>
Message-ID: <20131023132457.GD2458@localhost>

Hi Gupta,

On Wed, Oct 23, 2013 at 01:15:20PM +0000, Gupta, Pekon wrote:
> Hi,
> 
> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> [...]
> > FWIW, I have a Beaglebone with a 16-bit bus NAND attached to it.
> > 
> > Coincidentally, yesterday I was doing some tests as I'm ramping up the
> > NAND and I found that weird double nand_scan_ident() call.
> > The whole thing looks buggy to me, so I'm happy to help, review, test
> > and patches to take care of this.
> > 
> Yes, thanks .. that would be of great help.. 
> And may be your experience of Atmel drivers would help me here..
> 

It's not Atmel, but Marvell :-)

> *Correct, should not be double calls to nand_scan_ident()..*
> But there is a constrain in nand_base.c, that it does not allow ONFI
> page reading in x16 mode.. So how to overcome that..
> 
> I see the similar implementation in your ATMEL driver, it does not use
> NAND_BUSWIDTH_AUTO so how do you perform ONFI read
> for x16 devices ?
> drivers/mtd/nand/atmel_nand.c @@atmel_nand_probe()
> /* here you move to x16 mode based on your DT or platform data */
> 	if (host->board.bus_width_16)	/* 16-bit bus width */
> 		nand_chip->options |= NAND_BUSWIDTH_16;
> /* And then you call nand_scan_ident */
> /* first scan to find the device and get the page size */
> 	if (nand_scan_ident(mtd, 1, NULL)) {
> 		res = -ENXIO;
> 		goto err_scan_ident;
> 	}
> 
> Wouldn't this fail, _unless_ your device is listed in nand_flash_id[] ?
> because it would not be able to read ONFI params.. 
> Refer below commit.. 
> commit 0ce82b7f7b7373b16ecf7b5725e21e2975204500
> Author:     Matthieu CASTET <matthieu.castet at parrot.com>
> AuthorDate: 2013-01-16
> 
> 

Not my driver, but I'm taking a look at it now. Not sure if I'll get
into something here.

> 
> 
> > I'm using some TI SDK with some ancient v3.2.x (with no git history!),
> > but from this discussion it seems the issue is still present in
> > mainline.
> > 
> Aah sorry, then you might have some problem here in rebasing the
> patches. But still if you can, thanks much ..
> 

I'm currently trying mainline (just for this issue not for my product).
I just need some time to prepare the bootargs and write a DT node for
the NAND cape.

Again, not sure if I'll make some progress, but I'll give it a shot :-)
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From annulen at yandex.ru  Wed Oct 23 09:39:40 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Wed, 23 Oct 2013 17:39:40 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <CAP+RiCBSPAHc2aM9byRjhFVePRU-1ODL9aJvN2Y65S4Ddj4sDA@mail.gmail.com>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <183031382371160@web6m.yandex.ru>
 <CAP+RiCDKgRqi8_Y4OMqyJyCUpKJW5BVE=hNwp3WzQ7PuOMWGMw@mail.gmail.com>
 <139841382436609@web24g.yandex.ru>
 <CAP+RiCDVTMb6RE5kGCYSyMCF9JMpSUAM5jS4YPObkbBu=zD59g@mail.gmail.com>
 <300471382514034@web11h.yandex.ru>
 <CAP+RiCBSPAHc2aM9byRjhFVePRU-1ODL9aJvN2Y65S4Ddj4sDA@mail.gmail.com>
Message-ID: <133391382535580@web11h.yandex.ru>



23.10.2013, 16:49, "Brent Taylor" <motobud at gmail.com>:
> On Wed, Oct 23, 2013 at 2:40 AM, Konstantin Tokarev <annulen at yandex.ru> wrote:
>
>> ?23.10.2013, 09:26, "Brent Taylor" <motobud at gmail.com>:
>>> ?Konstantin,
>>> ????I did my testing with data from /dev/urandom (which I now realize
>>> ?wasn't the best choice of data source), but if I use /dev/zero (which
>>> ?actually causes data compression to occur), the decompressor fails. ?I
>>> ?don't know the internal workings of the lz4hc compressor or the lz4
>>> ?decompressor. ?I couldn't find any examples of any code in the kernel
>>> ?actually using the compressor. ?I've cc'ed the maintainers of the
>>> ?lz4hc_compress.c to see if they my have some more insight to the
>>> ?issue.
>> ?Does decompressor fail for you with the same error messages?
>>
>> ?Have you tried to copy my file to the volume? It looks like minimal test case
>> ?for my board, if I remove any line decompressor works fine.
>>
>> ?--
>> ?Regards,
>> ?Konstantin
>
> Yes, I get the same error, here's a dump from UBIFS when I cat a file
> filled with data from /dev/zero:
>
> UBIFS error (pid 4288): ubifs_decompress: cannot decompress 12 bytes,
> compressor lz4hc, error -22
> UBIFS error (pid 4288): read_block: bad data node (block 0, inode 71)
> ????????magic ?????????0x6101831
> ????????crc ???????????0xff61a078
> ????????node_type ?????1 (data node)
> ????????group_type ????0 (no node group)
> ????????sqnum ?????????2700
> ????????len ???????????60
> ????????key ???????????(71, data, 0)
> ????????size ??????????512
> ????????compr_typ ?????3
> ????????data size ?????12
> ????????data:
> ????????00000000: 1f 00 01 00 ff e8 50 00 00 00 00 00
> UBIFS error (pid 4288): do_readpage: cannot read page 0 of inode 71, error -22
> cat: /opt/data/zero.bin: Input/output error
>
> Steps to reproduce are:
> 1. ?Create a file with all zeros: dd if=/dev/zero bs=512 count=1
> of=/opt/data/zero.bin
> 2. ?Unmount ubifs and detach ubi partition
> 3. ?attach ubi partition and mount ubifs
> 4. cat /opt/data/zero.bin

Reproduced here.

-- 
Regards,
Konstantin


From ezequiel.garcia at free-electrons.com  Wed Oct 23 09:44:51 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 23 Oct 2013 10:44:51 -0300
Subject: [PATCH v10 10/10] mtd: nand: omap: remove selection of BCH
 ecc-scheme via KConfig
In-Reply-To: <1382172254-12448-11-git-send-email-pekon@ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-11-git-send-email-pekon@ti.com>
Message-ID: <20131023134450.GE2458@localhost>

Gupta,

I already have a question :-)

On Sat, Oct 19, 2013 at 02:14:14PM +0530, Pekon Gupta wrote:
> With OMAP NAND driver updates, selection of ecc-scheme:
> *DT enabled kernel*
>  	depends on ti,nand-ecc-opt and ti,elm-id DT bindings.
> *Non DT enabled kernel*
> 	depends on elm_dev and ecc-scheme passed along with platform-data
> 	from board file.
> 
> So, selection of ecc-scheme (BCH8 or BCH4) from KConfig can be removed
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/Kconfig | 40 ++++++----------------------------------
>  1 file changed, 6 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index d885298..93ae6a6 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -96,43 +96,15 @@ config MTD_NAND_OMAP2
>  
>  config MTD_NAND_OMAP_BCH
>  	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3

I'm wondering how are you testing this in your SOC_AM33XX board (which
is not ARCH_OMAP3). You probably have ARCH_OMAP3 always selected?

IMO, no need to depend on any ARCH_xxx, just make it depend on the driver
option itself, which already depends on ARCH_OMAP2PLUS (which is the bigger
SoC family).

Care to send a one-patch fix for that, so this *independent* bug can be
taken by Brian? Please add my Reported-by when you do so.

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Wed Oct 23 09:55:58 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 23 Oct 2013 13:55:58 +0000
Subject: [PATCH v10 10/10] mtd: nand: omap: remove selection of BCH
 ecc-scheme via KConfig
In-Reply-To: <20131023134450.GE2458@localhost>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-11-git-send-email-pekon@ti.com>
 <20131023134450.GE2458@localhost>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2A130@DBDE04.ent.ti.com>

> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> 
> Gupta,
> 
Please call me 'Pekon' :-)

[...]

> 
> I'm wondering how are you testing this in your SOC_AM33XX board (which
> is not ARCH_OMAP3). You probably have ARCH_OMAP3 always selected?
> 
Yes, omap2plus_defconfig is a super set..
arch/arm/configs/omap2plus_defconfig automatically enables ARCH_OMAP3.

> IMO, no need to depend on any ARCH_xxx, just make it depend on the
> driver 
> option itself, which already depends on ARCH_OMAP2PLUS (which is the
> bigger SoC family).
> 
> Care to send a one-patch fix for that, so this *independent* bug can be
> taken by Brian? Please add my Reported-by when you do so.
> 
Thanks. It's good to clean this dependency..
Yes, surely I'll send a independent patch with your reported-by..


with regards, pekon

From ezequiel.garcia at free-electrons.com  Wed Oct 23 10:13:53 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 23 Oct 2013 11:13:53 -0300
Subject: [PATCH v10 10/10] mtd: nand: omap: remove selection of BCH
 ecc-scheme via KConfig
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2A130@DBDE04.ent.ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-11-git-send-email-pekon@ti.com>
 <20131023134450.GE2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A130@DBDE04.ent.ti.com>
Message-ID: <20131023141352.GG2458@localhost>

Pekon,

On Wed, Oct 23, 2013 at 01:55:58PM +0000, Gupta, Pekon wrote:
> > 
> > I'm wondering how are you testing this in your SOC_AM33XX board (which
> > is not ARCH_OMAP3). You probably have ARCH_OMAP3 always selected?
> > 
> Yes, omap2plus_defconfig is a super set..
> arch/arm/configs/omap2plus_defconfig automatically enables ARCH_OMAP3.
> 

Yes, but I always remove what I won't use to reduce build time.

And  now that you bring this issue. IMHO, the AM33xx family is going
to be more and more widely used, so maybe introducing an am33xx_defconfig
makes sense.

Or is the trend to have the least possible amount of defconfigs?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From dwmw2 at infradead.org  Wed Oct 23 10:33:51 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Wed, 23 Oct 2013 15:33:51 +0100
Subject: [PATCH] mtd: gpmi: fix the ecc regression
In-Reply-To: <20131022133446.GA2766@kartoffel>
References: <1382418628-4521-1-git-send-email-b32955@freescale.com>
 <20131022133446.GA2766@kartoffel>
Message-ID: <1382538831.8522.27.camel@shinybook.infradead.org>

On Tue, 2013-10-22 at 14:34 +0100, Mark Rutland wrote:
> 
> If the patch you referenced changed the layout without maintainng backwards
> compatibility, it sounds like it is broken and has caused a regression.
> 
> This is a work around, not a fix.

Kind of.

Yes, the best answer right now at -rc6 might be to just revert the
functional change and *always* use legacy_set_geometry().

And the name of the proposed new DT property could certainly do with
some improvement.

But fundamentally, the "Linux-specific" bit was already there as an
implicit assumption in the bindings, because there was a de facto
standard for how you lay out the ECC "as legacy_set_geometry() does it".

Now we want to set an option to indicate that it should be automatically
calculated from the properties of the chip (as set_geometry_by_ecc_info
does it), rather than done the old way. And it's not unreasonable to
have that as a DT property. We're no *more* Linux-specific than we were
before.

But perhaps it's too late for 3.12 to do that?

-- 
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: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131023/e2499aca/attachment.bin>

From ezequiel.garcia at free-electrons.com  Wed Oct 23 10:46:53 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 23 Oct 2013 11:46:53 -0300
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20131023132457.GD2458@localhost>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com> <20131023125516.GA2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A0CB@DBDE04.ent.ti.com>
 <20131023132457.GD2458@localhost>
Message-ID: <20131023144652.GI2458@localhost>

Pekon,

On Wed, Oct 23, 2013 at 10:24:57AM -0300, Ezequiel Garcia wrote:
[..]
> 
> I'm currently trying mainline (just for this issue not for my product).
> I just need some time to prepare the bootargs and write a DT node for
> the NAND cape.
> 
> Again, not sure if I'll make some progress, but I'll give it a shot :-)

I won't be able to make too much progress without some help or without
squeezing my brains out :P

Care to push some git branch on some random repo with DT support for
the NAND cape in the Beaglebone?

Please base it in either some recent l2-mtd or some tag from Linus.

Thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From dedekind1 at gmail.com  Wed Oct 23 11:40:08 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 23 Oct 2013 16:40:08 +0100
Subject: [PATCH] UBI: optimize erase-header IO read checks
In-Reply-To: <1367212058-10429-1-git-send-email-pekon@ti.com>
References: <1367212058-10429-1-git-send-email-pekon@ti.com>
Message-ID: <1382542808.8882.0.camel@karhu.quadriga.com>


On Mon, 2013-04-29 at 10:37 +0530, Gupta, Pekon wrote:
...
> Signed-off-by: Gupta, Pekon <pekon at ti.com>

I do generally understand what you are trying to do in this patch, but I
cannot carefully review it, because it is too big, just like the second
patch.

It really should be split. I think you should start with a preparation
patch which does not change the current logic, but just transforms the
code to using a switch statement.

Then you should start modifying the big switch statement, preferably one
step per patch, explaining each step. I guess the first step would be
removing the magic numbers check. Another step would be removing the
0xFF comparison. Etc.

Then your work could be reviewed, and we could be somewhat confident
that it does not break anything.

> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> index bf79def..624365b 100644
> --- a/drivers/mtd/ubi/io.c
> +++ b/drivers/mtd/ubi/io.c
> @@ -537,7 +537,7 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
>  
>  		err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
>  		if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
> -		    err1 == UBI_IO_FF)
> +		    err1 == UBI_IO_FF || err1 == UBI_IO_FF_BITFLIPS)

Let's check this change, for example.

The comments in this function say that it is important to have both EC
and VID headers invalid. But here it looks like you allow the EC header
to be valid, but just have a bitflip. But in this function we do want to
make sure both headers are invalid...

This looks incorrect. But may be I just did not understand you changes
in the 'ubi_io_read_ec_hdr()' function.

Anyway, we really need to do everything in a more controllable and
reviewable manner.

-- 
Best Regards,
Artem Bityutskiy

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Wed Oct 23 12:17:12 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Wed, 23 Oct 2013 17:17:12 +0100
Subject: problem with ecc errors and ubifs
In-Reply-To: <alpine.DEB.2.00.1310221356080.28562@lnxricardw.se.axis.com>
References: <52666705.8040000@ammonit.com>
 <alpine.DEB.2.00.1310221356080.28562@lnxricardw.se.axis.com>
Message-ID: <1382545032.8882.3.camel@karhu.quadriga.com>

On Tue, 2013-10-22 at 14:05 +0200, Ricard Wanderlof wrote:
> I know there have been discussions that when using ECC that can correct 
> more than a single bit in a given area, to not trigger scrubbing as soon 
> as a single bit goes bad, but use a threshold mechanism, so that scrubbing 
> is triggered first when, say, half the maximum amount of bits need 
> correcting (e.g. in your case when 4 bits need correcting), the reason 
> being that flashes which require multibit ecc tend to have bits here and 
> there that flip rather quickly after writing, so triggering on them leads 
> to undue scrubbing and hence wear on the flash.

We already have this stuff in mainline kernels for rather long time. See
the 'bitflip_threshold' variable in the mtd_info data structures. We
have a good piece of documentation in
Documentation/ABI/testing/sysfs-class-mtd

-- 
Best Regards,
Artem Bityutskiy



From computersforpeace at gmail.com  Wed Oct 23 12:43:32 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 09:43:32 -0700
Subject: [PATCH] driver/mtd/IFC: Add support of 8K page size NAND flash
In-Reply-To: <1380021083-15986-1-git-send-email-prabhakar@freescale.com>
References: <1380021083-15986-1-git-send-email-prabhakar@freescale.com>
Message-ID: <20131023164332.GU23337@ld-irv-0074.broadcom.com>

On Tue, Sep 24, 2013 at 04:41:23PM +0530, Prabhakar Kushwaha wrote:
> Current IFC driver supports till 4K page size NAND flash.
> Add support of 8K Page size NAND flash
>   - Add nand_ecclayout for 4 bit & 8 bit ecc
>   - Defines constants
>   - also fix ecc.strength for 8bit ecc of 8K page size NAND
> 
> Signed-off-by: Prabhakar Kushwaha <prabhakar at freescale.com>

These ECC layouts are rather horrendous and large, but they're the best
we've got...

Pushed to l2-mtd.git with compile testing only. Let me know if there are
any Tested-by's (or NAK's).

Brian

> ---
>  git://git.infradead.org/linux-mtd.git branch master
>  
>  arch/powerpc/include/asm/fsl_ifc.h |    2 +
>  drivers/mtd/nand/fsl_ifc_nand.c    |   77 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 79 insertions(+)
> 
> diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h
> index b8a4b9b..f49ddb1 100644
> --- a/arch/powerpc/include/asm/fsl_ifc.h
> +++ b/arch/powerpc/include/asm/fsl_ifc.h
> @@ -93,6 +93,7 @@
>  #define CSOR_NAND_PGS_512		0x00000000
>  #define CSOR_NAND_PGS_2K		0x00080000
>  #define CSOR_NAND_PGS_4K		0x00100000
> +#define CSOR_NAND_PGS_8K		0x00180000
>  /* Spare region Size */
>  #define CSOR_NAND_SPRZ_MASK		0x0000E000
>  #define CSOR_NAND_SPRZ_SHIFT		13
> @@ -102,6 +103,7 @@
>  #define CSOR_NAND_SPRZ_210		0x00006000
>  #define CSOR_NAND_SPRZ_218		0x00008000
>  #define CSOR_NAND_SPRZ_224		0x0000A000
> +#define CSOR_NAND_SPRZ_CSOR_EXT		0x0000C000
>  /* Pages Per Block */
>  #define CSOR_NAND_PB_MASK		0x00000700
>  #define CSOR_NAND_PB_SHIFT		8
> diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
> index 317a771..a14885b 100644
> --- a/drivers/mtd/nand/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/fsl_ifc_nand.c
> @@ -135,6 +135,69 @@ static struct nand_ecclayout oob_4096_ecc8 = {
>  	.oobfree = { {2, 6}, {136, 82} },
>  };
>  
> +/* 8192-byte page size with 4-bit ECC */
> +static struct nand_ecclayout oob_8192_ecc4 = {
> +	.eccbytes = 128,
> +	.eccpos = {
> +		8, 9, 10, 11, 12, 13, 14, 15,
> +		16, 17, 18, 19, 20, 21, 22, 23,
> +		24, 25, 26, 27, 28, 29, 30, 31,
> +		32, 33, 34, 35, 36, 37, 38, 39,
> +		40, 41, 42, 43, 44, 45, 46, 47,
> +		48, 49, 50, 51, 52, 53, 54, 55,
> +		56, 57, 58, 59, 60, 61, 62, 63,
> +		64, 65, 66, 67, 68, 69, 70, 71,
> +		72, 73, 74, 75, 76, 77, 78, 79,
> +		80, 81, 82, 83, 84, 85, 86, 87,
> +		88, 89, 90, 91, 92, 93, 94, 95,
> +		96, 97, 98, 99, 100, 101, 102, 103,
> +		104, 105, 106, 107, 108, 109, 110, 111,
> +		112, 113, 114, 115, 116, 117, 118, 119,
> +		120, 121, 122, 123, 124, 125, 126, 127,
> +		128, 129, 130, 131, 132, 133, 134, 135,
> +	},
> +	.oobfree = { {2, 6}, {136, 208} },
> +};
> +
> +/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */
> +static struct nand_ecclayout oob_8192_ecc8 = {
> +	.eccbytes = 256,
> +	.eccpos = {
> +		8, 9, 10, 11, 12, 13, 14, 15,
> +		16, 17, 18, 19, 20, 21, 22, 23,
> +		24, 25, 26, 27, 28, 29, 30, 31,
> +		32, 33, 34, 35, 36, 37, 38, 39,
> +		40, 41, 42, 43, 44, 45, 46, 47,
> +		48, 49, 50, 51, 52, 53, 54, 55,
> +		56, 57, 58, 59, 60, 61, 62, 63,
> +		64, 65, 66, 67, 68, 69, 70, 71,
> +		72, 73, 74, 75, 76, 77, 78, 79,
> +		80, 81, 82, 83, 84, 85, 86, 87,
> +		88, 89, 90, 91, 92, 93, 94, 95,
> +		96, 97, 98, 99, 100, 101, 102, 103,
> +		104, 105, 106, 107, 108, 109, 110, 111,
> +		112, 113, 114, 115, 116, 117, 118, 119,
> +		120, 121, 122, 123, 124, 125, 126, 127,
> +		128, 129, 130, 131, 132, 133, 134, 135,
> +		136, 137, 138, 139, 140, 141, 142, 143,
> +		144, 145, 146, 147, 148, 149, 150, 151,
> +		152, 153, 154, 155, 156, 157, 158, 159,
> +		160, 161, 162, 163, 164, 165, 166, 167,
> +		168, 169, 170, 171, 172, 173, 174, 175,
> +		176, 177, 178, 179, 180, 181, 182, 183,
> +		184, 185, 186, 187, 188, 189, 190, 191,
> +		192, 193, 194, 195, 196, 197, 198, 199,
> +		200, 201, 202, 203, 204, 205, 206, 207,
> +		208, 209, 210, 211, 212, 213, 214, 215,
> +		216, 217, 218, 219, 220, 221, 222, 223,
> +		224, 225, 226, 227, 228, 229, 230, 231,
> +		232, 233, 234, 235, 236, 237, 238, 239,
> +		240, 241, 242, 243, 244, 245, 246, 247,
> +		248, 249, 250, 251, 252, 253, 254, 255,
> +		256, 257, 258, 259, 260, 261, 262, 263,
> +	},
> +	.oobfree = { {2, 6}, {264, 80} },
> +};
>  
>  /*
>   * Generic flash bbt descriptors
> @@ -872,11 +935,25 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
>  		} else {
>  			layout = &oob_4096_ecc8;
>  			chip->ecc.bytes = 16;
> +			chip->ecc.strength = 8;
>  		}
>  
>  		priv->bufnum_mask = 1;
>  		break;
>  
> +	case CSOR_NAND_PGS_8K:
> +		if ((csor & CSOR_NAND_ECC_MODE_MASK) ==
> +		    CSOR_NAND_ECC_MODE_4) {
> +			layout = &oob_8192_ecc4;
> +		} else {
> +			layout = &oob_8192_ecc8;
> +			chip->ecc.bytes = 16;
> +			chip->ecc.strength = 8;
> +		}
> +
> +		priv->bufnum_mask = 0;
> +	break;
> +
>  	default:
>  		dev_err(priv->dev, "bad csor %#x: bad page size\n", csor);
>  		return -ENODEV;
> -- 
> 1.7.9.5
> 
> 
> 
> 


From computersforpeace at gmail.com  Wed Oct 23 12:44:11 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 09:44:11 -0700
Subject: [PATCH] driver/mtd/ifc: Read Status while programming NAND flash
In-Reply-To: <1380780401-6640-1-git-send-email-prabhakar@freescale.com>
References: <1380780401-6640-1-git-send-email-prabhakar@freescale.com>
Message-ID: <20131023164411.GV23337@ld-irv-0074.broadcom.com>

On Thu, Oct 03, 2013 at 11:36:41AM +0530, Prabhakar Kushwaha wrote:
> as per controller description,
>   "While programming a NAND flash, status read should never skipped.
>    Because it may happen that a new command is issued to the NAND Flash,
>    even when the device has not yet finished processing the previous request.
>    This may result in unpredictable behaviour."
> 
> IFC controller never polls for R/B signal after command send. It just return
> control to software. This behaviour may not occur with NAND flash access.
> because new commands are sent after polling R/B signal. But it may happen
> in scenario where GPCM-ASIC and NAND flash device are working simultaneously.
> 
> Update the controller driver to take care of this requirement
> 
> Signed-off-by: Prabhakar Kushwaha <prabhakar at freescale.com>

Pushed to l2-mtd.git. Thanks!

Brian


From yann.collet.73 at gmail.com  Wed Oct 23 14:19:48 2013
From: yann.collet.73 at gmail.com (Yann Collet)
Date: Wed, 23 Oct 2013 18:19:48 +0000 (UTC)
Subject: lz4hc compression in UBIFS?
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
Message-ID: <loom.20131023T201657-894@post.gmane.org>

UBIFS error (pid 4288): ubifs_decompress: cannot decompress 12 bytes,
(...)
        data size      12
        data:
        00000000: 1f 00 01 00 ff e8 50 00 00 00 00 00


The compressed format is correct.
It describes a flow of 00, of size ~500.

So the problem seems more likely on the decompression side.

Are you sure you are providing "12" as the "input size" parameter ? and that 
the "maximum output size" parameter is correctly provided ? (i.e. >= to 
original data size)


Regards 






From computersforpeace at gmail.com  Wed Oct 23 16:40:42 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 13:40:42 -0700
Subject: [PATCH] mtd: m25p80: add support for Macronix mx25l3255e
Message-ID: <1382560842-428-1-git-send-email-computersforpeace@gmail.com>

A new 32Gbit SPI NOR flash from Macronix. Nothing special.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Cc: Marek Vasut <marex at denx.de>
---
 drivers/mtd/devices/m25p80.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 8d6c87be..72c37f0 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -778,6 +778,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
 	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
+	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
 	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-- 
1.8.4



From computersforpeace at gmail.com  Wed Oct 23 18:09:50 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 15:09:50 -0700
Subject: UBIFS: assert failed in ubifs_tnc_next_ent
Message-ID: <20131023220950.GW23337@ld-irv-0074.broadcom.com>

Hi all,

I'm running a 3.8 kernel with UBIFS. I can trigger some UBIFS asserts
after a few hours of running a filesystem benchmark (like bonnie++) in a
loop. I've tried backporting a few UBIFS bugfixes, e.g.:

  commit 605c912bb843c024b1ed173dc427cd5c08e5d54d
  Author: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
  Date:   Fri Jun 28 14:15:15 2013 +0300

      UBIFS: fix a horrid bug

  commit 33f1a63ae84dfd9ad298cf275b8f1887043ced36
  Author: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
  Date:   Fri Jun 28 14:15:14 2013 +0300

      UBIFS: prepare to fix a horrid bug

They did not help.

I have run various tests (including the MTD read/page/stress test
modules as well as a few hand-rolled user-space tests), and my driver
seems to be working fine.

I am not able to reproduce the failure on nandsim with either my 3.8
kernel/embedded hardware or with Linus' head of tree on my PC. Perhaps
there's something related to NAND geometry or to driver timing that
uncovers the filesystem bug.

Do you have any idea what would cause this type of problem?

Thanks,
Brian

NAND chip:

  NAND device: Manufacturer ID: 0x2c, Chip ID: 0x44 (Micron MT29F32G08CBADAWP), 4096MiB, page size: 8192, OOB size: 744

Log:

(I didn't enable UBI/UBIFS debugging messages yet, because the test
takes a few hours to trigger this, and I would be overwhelmed with logs
before I could here...)

UBIFS assert failed in ubifs_tnc_next_ent at 2776 (pid 2143)
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270)
[<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
UBIFS error (pid 2143): ubifs_validate_entry: bad extended attribute entry node
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0)
[<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0) from [<c01a5670>] (matches_name.clone.22+0xbc/0xd0)
[<c01a5670>] (matches_name.clone.22+0xbc/0xd0) from [<c01a56cc>] (resolve_collision+0x48/0x304)
[<c01a56cc>] (resolve_collision+0x48/0x304) from [<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270)
[<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
	magic          0x6101831
	crc            0x2715b167
	node_type      0 (inode node)
	group_type     2 (last of node group)
	sqnum          80750934
	len            160
	key            (5899336, inode)
	creat_sqnum    80641253
	size           236552
	nlink          2
	atime          13941.0
	mtime          13963.0
	ctime          13963.0
	uid            0
	gid            0
	mode           16832
	flags          0x1
	xattr_cnt      0
	xattr_size     0
	xattr_names    0
	compr_type     0x0
	data len       0
UBIFS error (pid 2143): ubifs_readdir: cannot find next direntry, error -22
UBIFS assert failed in ubifs_tnc_next_ent at 2776 (pid 2143)
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270)
[<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
UBIFS error (pid 2143): ubifs_validate_entry: bad extended attribute entry node
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0)
[<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0) from [<c01a5670>] (matches_name.clone.22+0xbc/0xd0)
[<c01a5670>] (matches_name.clone.22+0xbc/0xd0) from [<c01a56cc>] (resolve_collision+0x48/0x304)
[<c01a56cc>] (resolve_collision+0x48/0x304) from [<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270)
[<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
	magic          0x6101831
	crc            0xef854d68
	node_type      0 (inode node)
	group_type     2 (last of node group)
	sqnum          80750937
	len            160
	key            (5899336, inode)
	creat_sqnum    80641253
	size           236488
	nlink          2
	atime          13941.0
	mtime          13963.0
	ctime          13963.0
	uid            0
	gid            0
	mode           16832
	flags          0x1
	xattr_cnt      0
	xattr_size     0
	xattr_names    0
	compr_type     0x0
	data len       0
UBIFS error (pid 2143): ubifs_readdir: cannot find next direntry, error -22


From peter at korsgaard.com  Wed Oct 23 18:31:47 2013
From: peter at korsgaard.com (Peter Korsgaard)
Date: Thu, 24 Oct 2013 00:31:47 +0200
Subject: [PATCH] mtd: m25p80: add support for Macronix mx25l3255e
In-Reply-To: <1382560842-428-1-git-send-email-computersforpeace@gmail.com>
 (Brian Norris's message of "Wed, 23 Oct 2013 13:40:42 -0700")
References: <1382560842-428-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <8738nraab0.fsf@dell.be.48ers.dk>

>>>>> "Brian" == Brian Norris <computersforpeace at gmail.com> writes:

 > A new 32Gbit SPI NOR flash from Macronix. Nothing special.

Presumably you mean Mbit?

-- 
Bye, Peter Korsgaard


From computersforpeace at gmail.com  Wed Oct 23 18:36:18 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 15:36:18 -0700
Subject: [PATCH] mtd: m25p80: add support for Macronix mx25l3255e
In-Reply-To: <8738nraab0.fsf@dell.be.48ers.dk>
References: <1382560842-428-1-git-send-email-computersforpeace@gmail.com>
 <8738nraab0.fsf@dell.be.48ers.dk>
Message-ID: <CAN8TOE8u4-Qe5Raw8dnuppvrWJms-N1ogXdTNLhFBNJTxvkf0Q@mail.gmail.com>

On Wed, Oct 23, 2013 at 3:31 PM, Peter Korsgaard <peter at korsgaard.com> wrote:
>>>>>> "Brian" == Brian Norris <computersforpeace at gmail.com> writes:
>
>  > A new 32Gbit SPI NOR flash from Macronix. Nothing special.
>
> Presumably you mean Mbit?

Yes. In fact, this very thought popped into my head an hour ago, where
I thought I recalled mistyping Mbit as Gbit...

I'll fix this and send v2. Thanks.

Brian


From computersforpeace at gmail.com  Wed Oct 23 18:37:55 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 15:37:55 -0700
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <5264A220.2070900@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>
 <5260DA32.4090502@freescale.com>
 <CAN8TOE8xDdRF4Hf+p4JMAixWfkxkbKCZB-fqpPA6yiMHYm=Qew@mail.gmail.com>
 <5264A220.2070900@freescale.com>
Message-ID: <20131023223755.GX23337@ld-irv-0074.broadcom.com>

On Mon, Oct 21, 2013 at 11:40:16AM +0800, Huang Shijie wrote:
> ? 2013?10?19? 10:01, Brian Norris ??:
> > Yes, I seem to have overlooked this set. I think it must have come in
> > parallel with your MLC patch set, so I delayed it until the MLC patch
> > set settled down?
> >
> this patch set has no relationship with MLC patch.

Well, it did touch the same driver, and your patch set kept evolving so
I chose to focus on just one of your patch sets at a time there...

I'll take a look now.

> > Anyway, I'll revisit this soon. But I probably need to take care of
> > your mtd-utils updates first, since they should go along with the MLC
> > patch set.
> >
> > And on top of that (to update the world on daily status), I seem to be
> > tripping over some UBIFS bugs that are inhibiting the validation I'm
> > trying to do for some new hardware. So, I'm all-around pretty busy!
> > I'll get myself together next week, hopefully.
> understood.
> 
> 
> I am too busy too, i am starting to code the Qspi driver now.
> I was blocked by a bluetooth/uart/dma issue last month.
> > In the meantime, other people's code could use some extra eyes. I know
> > Ezequiel just sent out a 27 (!) patch series today. There's also the
> > pending cmdline.c patch from months ago, where Cai Zhiyong wanted to
> > migrate our command line partition parser to a common
> > block/cmdline-parser.c. Part of her work (for block devices) is
> I like Cai zhiyong's patch. But I do not have time to test his patch.

Well, this represents a bad community mentality, where people have time
to submit plenty of code for their own drivers, and ask a lot from
maintainers to review and merge their code, yet they do not have any
time to review others' work. I believe that bearing the sole
responsibility of code review is a major contributing factor in both
Artem's and my long latency to merging patches.

That said, I understand that people get very busy sometimes, and I don't
mean to particularly focus on you, Huang. This is a general pattern that
I've seen, and I have done the same thing previously, where I simply did
not have (and did not make) time to review others' work much.

Brian


From computersforpeace at gmail.com  Wed Oct 23 18:40:03 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 15:40:03 -0700
Subject: [PATCH v2] mtd: m25p80: add support for Macronix mx25l3255e
Message-ID: <1382568003-2356-1-git-send-email-computersforpeace@gmail.com>

A new 32Mbit SPI NOR flash from Macronix. Nothing special.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Cc: Marek Vasut <marex at denx.de>
---
v2: correct "Gbit" to "MBit" in patch description

 drivers/mtd/devices/m25p80.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 8d6c87be..72c37f0 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -778,6 +778,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
 	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
+	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
 	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-- 
1.8.4



From computersforpeace at gmail.com  Wed Oct 23 18:59:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 15:59:54 -0700
Subject: [PATCH V2 0/4] mtd: gpmi: support two nand chips at most
In-Reply-To: <1377595747-21033-1-git-send-email-b32955@freescale.com>
References: <1377595747-21033-1-git-send-email-b32955@freescale.com>
Message-ID: <20131023225954.GY23337@ld-irv-0074.broadcom.com>

On Tue, Aug 27, 2013 at 05:29:03PM +0800, Huang Shijie wrote:
> Current gpmi-nand driver only supports one chips. But we may meet
> some embarrassing situation, such as Micron MT29F32G08QAA.
> This nand chip has two DIEs internally. Each die has its own chip select pin,
> so this chip acts as two nand chips.
> 
> If we only scan one chip, we may find that we only get 2G for this chip,
> but in actually, this chip's size is 4G.
> 
> So scan two chips by default.
> 
> In order to support two nand chips, we have to do the following:
>    1.) Decouple the chip select from the DMA channel,
>        We can use the dma 0 to access all the nand chips.
> 
>    2.) fix the wrong method of checking the ready/busy status.
>       In the imx6, all the ready/busy pins are binding together, we
>       should check ready/busy status of chip 0 for the all the chips. 
> 
> Tested this patch set with MT29F32G08QAA.

I fixed up some typos in patch 4 and pushed the series. Thanks!

Brian


From computersforpeace at gmail.com  Wed Oct 23 20:22:53 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 17:22:53 -0700
Subject: [PATCH 0/3]Add quad/memory mapped support for SPI flash.
In-Reply-To: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <20131024002253.GZ23337@ld-irv-0074.broadcom.com>

Hi Sourav,

I must admit, I missed some of this series due to a combination of
strange Gmail filtering (I just learned that a filter for "PATCH"
doesn't match "PATCHv3" in Gmail...) and the inconsistent naming in your
patch series. (I see PATCH, PATCHv3, and RFC/PATCH.) I'll try to prevent
that in the future.

On Wed, Oct 09, 2013 at 08:54:41PM +0530, Sourav Poddar wrote:
> This patch add quad/memory mapped support in flash driver(m25p80).

Does "memory mapped" supoprt need to be in the same series as quad read
support? Those are very different topics, it seems.

> Added support for quad memory mapped for TI qspi controller also.
> 
> This patch has been tested with some internal dts data.

Your patches use new DT bindings which are not documented. If you are
adding bindings, please document them in
Documentation/devicetree/bindings/ and CC devicetree at vger.kernel.org.
(You only need to CC them for the binding documenation, not necessarily
all your code changes.)

That being said, I'm not sure you need some of the bindings that you're
using. I'll comment on the affected patch(es).

Brian


From computersforpeace at gmail.com  Wed Oct 23 21:06:19 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 18:06:19 -0700
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
Message-ID: <20131024010619.GA23337@ld-irv-0074.broadcom.com>

+ others

On Wed, Oct 09, 2013 at 08:54:43PM +0530, Sourav Poddar wrote:
> Some flash also support quad read mode.
> Adding support for adding quad mode in m25p80
> for spansion and macronix flash.
> 
> Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
> v2->v3:
> Add macronix flash support
>  drivers/mtd/devices/m25p80.c |  184 ++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 176 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 26b14f9..dc9bcbf 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -41,6 +41,7 @@
>  #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
>  #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
>  #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
> +#define	OPCODE_QUAD_READ        0x6b    /* QUAD READ */
>  #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
>  #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
>  #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
> @@ -48,6 +49,7 @@
>  #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
>  #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
>  #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
> +#define	OPCODE_RDCR		0x35    /* Read configuration register */
>  
>  /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>  #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
> @@ -76,6 +78,10 @@
>  #define	SR_BP2			0x10	/* Block protect 2 */
>  #define	SR_SRWD			0x80	/* SR write protect */
>  
> +/* Configuration Register bits. */
> +#define SPAN_QUAD_CR_EN		0x2	/* Spansion Quad I/O */
> +#define MACR_QUAD_SR_EN		0x40	/* Macronix Quad I/O */

Perhaps CR_ can be the prefix, like the status register SR_ macros? So:

  CR_QUAD_EN_SPAN
  CR_QUAD_EN_MACR

> +
>  /* Define max times to check status register before we give up. */
>  #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
>  #define	MAX_CMD_SIZE		5
> @@ -95,6 +101,7 @@ struct m25p {
>  	u8			program_opcode;
>  	u8			*command;
>  	bool			fast_read;
> +	bool			quad_read;
>  };
>  
>  static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
> @@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)
>  	return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
>  }
>  
> +/* Read the configuration register, returning its value in the location
> + * Return the configuration register value.
> + * Returns negative if error occurred.
> +*/
> +static int read_cr(struct m25p *flash)
> +{
> +	u8 code = OPCODE_RDCR;
> +	int ret;
> +	u8 val;
> +
> +	ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
> +	if (ret < 0) {
> +		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
> +		return ret;
> +	}
> +
> +	return val;
> +}
> +
>  /*
>   * Enable/disable 4-byte addressing mode.
>   */
> @@ -336,6 +362,122 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
>  	return 0;
>  }
>  
> +/* Write status register and configuration register with 2 bytes
> +* The first byte will be written to the status register, while the second byte
> +* will be written to the configuration register.
> +* Returns negative if error occurred.
> +*/

Not quite the correct multi-line comment style.

/*
 * It should be something like this. Note the asterisk alignment. You
 * also could wrap the right edge neatly to nearly 80 characters.
 */

> +static int write_sr_cr(struct m25p *flash, u16 val)
> +{
> +	flash->command[0] = OPCODE_WRSR;
> +	flash->command[1] = val & 0xff;
> +	flash->command[2] = (val >> 8);
> +
> +	return spi_write(flash->spi, flash->command, 3);
> +}
> +
> +static int macronix_quad_enable(struct m25p *flash)
> +{
> +	int ret, val;
> +	u8 cmd[2];
> +	cmd[0] = OPCODE_WRSR;
> +
> +	val = read_sr(flash);
> +	cmd[1] = val | MACR_QUAD_SR_EN;
> +	write_enable(flash);
> +
> +	spi_write(flash->spi, &cmd, 2);
> +
> +	if (wait_till_ready(flash))
> +		return 1;
> +
> +	ret = read_sr(flash);
> +	if (!(ret > 0 && (ret & MACR_QUAD_SR_EN))) {
> +		dev_err(&flash->spi->dev,
> +			"Macronix Quad bit not set");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int spansion_quad_enable(struct m25p *flash)
> +{
> +	int ret;
> +	int quad_en = SPAN_QUAD_CR_EN << 8;
> +
> +	write_enable(flash);
> +
> +	ret = write_sr_cr(flash, quad_en);
> +	if (ret < 0) {
> +		dev_err(&flash->spi->dev,
> +			"error while writing configuration register");
> +		return -EINVAL;
> +	}
> +
> +	/* read back and check it */
> +	ret = read_cr(flash);
> +	if (!(ret > 0 && (ret & SPAN_QUAD_CR_EN))) {
> +		dev_err(&flash->spi->dev,
> +			"Spansion Quad bit not set");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
> +	size_t *retlen, u_char *buf)
> +{

This function only has 2 meaningful lines difference from m25p80_read(),
no? I'd consider combining them. You only need a simple bool/flag to
tell whether we're in quad mode + you can re-use the 'read_opcode' field
of struct m25p.

> +	struct m25p *flash = mtd_to_m25p(mtd);
> +	struct spi_transfer t[2];
> +	struct spi_message m;
> +	uint8_t opcode;
> +
> +	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
> +			__func__, (u32)from, len);
> +
> +	spi_message_init(&m);
> +	memset(t, 0, (sizeof(t)));
> +
> +	t[0].tx_buf = flash->command;
> +	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);

This is the first of 2 lines that are different from m25p80_read(). It
can easily be combined with the existing read implementation.

> +	spi_message_add_tail(&t[0], &m);
> +
> +	t[1].rx_buf = buf;
> +	t[1].len = len;
> +	t[1].rx_nbits = SPI_NBITS_QUAD;

This is the second of 2 different lines. You can change m25p80_read() to
have something like this:

	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;

> +	spi_message_add_tail(&t[1], &m);
> +
> +	mutex_lock(&flash->lock);
> +
> +	/* Wait till previous write/erase is done. */
> +	if (wait_till_ready(flash)) {
> +		/* REVISIT status return?? */
> +		mutex_unlock(&flash->lock);
> +		return 1;
> +	}
> +
> +	/* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
> +	 * clocks; and at this writing, every chip this driver handles
> +	 * supports that opcode.
> +	*/

What? It seems you blindly copied/edited the already-out-of-date comment
from m25p80_read().

> +
> +	/* Set up the write data buffer. */
> +	opcode = flash->read_opcode;
> +	flash->command[0] = opcode;
> +	m25p_addr2cmd(flash, from, flash->command);
> +
> +	spi_sync(flash->spi, &m);
> +
> +	*retlen = m.actual_length - m25p_cmdsz(flash) -
> +			(flash->quad_read ? 1 : 0);
> +
> +	mutex_unlock(&flash->lock);
> +
> +	return 0;
> +}
> +
>  /*
>   * Read an address range from the flash chip.  The address range
>   * may be any size provided it is within the physical boundaries.
> @@ -928,6 +1070,7 @@ static int m25p_probe(struct spi_device *spi)
>  	unsigned			i;
>  	struct mtd_part_parser_data	ppdata;
>  	struct device_node __maybe_unused *np = spi->dev.of_node;
> +	int ret;
>  
>  #ifdef CONFIG_MTD_OF_PARTS
>  	if (!of_device_is_available(np))
> @@ -979,15 +1122,9 @@ static int m25p_probe(struct spi_device *spi)
>  		}
>  	}
>  
> -	flash = kzalloc(sizeof *flash, GFP_KERNEL);
> +	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
>  	if (!flash)
>  		return -ENOMEM;
> -	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
> -					GFP_KERNEL);
> -	if (!flash->command) {
> -		kfree(flash);
> -		return -ENOMEM;
> -	}

You're combining a bug fix with your feature addition. The size may be
off-by-one (which is insignificant in this case, I think, but still...)
so the kmalloc() does needs to move down, but it should be done before
this feature patch. (Sorry, I've had a patch queued up but didn't send
it out for a while. I think somebody sorta tried to fix this a while ago
but didn't send a proper patch.)

>  
>  	flash->spi = spi;
>  	mutex_init(&flash->lock);
> @@ -1015,7 +1152,6 @@ static int m25p_probe(struct spi_device *spi)
>  	flash->mtd.flags = MTD_CAP_NORFLASH;
>  	flash->mtd.size = info->sector_size * info->n_sectors;
>  	flash->mtd._erase = m25p80_erase;
> -	flash->mtd._read = m25p80_read;
>  
>  	/* flash protection support for STmicro chips */
>  	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
> @@ -1067,6 +1203,38 @@ static int m25p_probe(struct spi_device *spi)
>  
>  	flash->program_opcode = OPCODE_PP;
>  
> +	flash->quad_read = false;
> +	if (spi->mode && SPI_RX_QUAD)

You're looking for bitwise '&', not logical '&&'.

> +		flash->quad_read = true;

But you can just replace the previous 3 lines with:

	flash->quad_read = spi->mode & SPI_RX_QUAD;

or this, if you really want be careful about the bit position:

	flash->quad_read = !!(spi->mode & SPI_RX_QUAD);

> +
> +	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
> +				(flash->quad_read ? 1 : 0)), GFP_KERNEL);

That's an ugly conditional. Maybe we just want to increase MAX_CMD_SIZE
and be done with it? Saving an extra byte is not helping anyone (and I
think pretty much everyone always has fast_read==true anyway).

> +	if (!flash->command) {
> +		kfree(flash);
> +		return -ENOMEM;
> +	}
> +
> +	if (flash->quad_read) {
> +		if (of_property_read_bool(np, "macronix,quad_enable")) {

As Jagan mentioned, I think we want this to be discoverable from within
m25p80.c. I don't think we should require it to be in DT. (We could
still support a DT binding just in case, but I think the majority
use-case should be easier to have a flag in the ID table; and if we ever
support SFDP, that could complement the flag approach nicely.)

Also, be sure to add a documentation patch for the DT binding if you
really need the binding.

> +			ret = macronix_quad_enable(flash);
> +			if (ret) {
> +				dev_err(&spi->dev,
> +					"error enabling quad");
> +				return -EINVAL;
> +			}
> +		} else if (of_property_read_bool(np, "spansion,quad_enable")) {

Ditto on the binding. I don't think it's necessary, and I would prefer
we go with the ID table flag or SFDP. But if you need it, document it.

> +			ret = spansion_quad_enable(flash);
> +			if (ret) {
> +				dev_err(&spi->dev,
> +					"error enabling quad");
> +				return -EINVAL;
> +			}
> +		} else
> +			dev_dbg(&spi->dev, "quad enable not supported");

...and if quad enable is not supported, we just blaze on to use quad
mode anyway?? No, I think this needs to be rewritten so that we only set
flash->quad_read = true when all of the following are true:

(1) the SPI controller supports quad I/O
(2) the flash supports it (i.e., after we see that the device supports
    it in the ID table/DT/SFDP) and
(3) we have successfully run one of the quad-enable commands

Then if you follow my advice on unifying m25p80_quad_read() and
m25p80_read(), you'll never have a mismatch between flash->quad_read,
the state of the flash, and the assigned flash->mtd._read callback
function. We will trivially fall back to single-I/O read if anything
fails, too.

> +		flash->mtd._read = m25p80_quad_read;
> +	} else
> +		flash->mtd._read = m25p80_read;

This mtd._read callback assignment should not need to be touched.

> +
>  	if (info->addr_width)
>  		flash->addr_width = info->addr_width;
>  	else if (flash->mtd.size > 0x1000000) {

Brian


From computersforpeace at gmail.com  Wed Oct 23 21:31:50 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 18:31:50 -0700
Subject: UBIFS: assert failed in ubifs_tnc_next_ent
In-Reply-To: <20131023220950.GW23337@ld-irv-0074.broadcom.com>
References: <20131023220950.GW23337@ld-irv-0074.broadcom.com>
Message-ID: <20131024013150.GB23337@ld-irv-0074.broadcom.com>

On Wed, Oct 23, 2013 at 03:09:50PM -0700, Brian Norris wrote:
> I am not able to reproduce the failure on nandsim with either my 3.8
> kernel/embedded hardware or with Linus' head of tree on my PC. Perhaps
> there's something related to NAND geometry or to driver timing that
> uncovers the filesystem bug.

Scratch that. It just took a lot longer (over 700 runs of bonnie++ vs.
100 to 200 on real hardware), but I was able to reproduce the bug with
nandsim on 3.8. I'll retry on 3.12-rc and with a few extra backported
fixes on 3.8.

The asserts using nandsim:

UBIFS assert failed in ubifs_tnc_next_ent at 2776 (pid 4262)
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270)
[<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
UBIFS error (pid 4262): ubifs_validate_entry: bad extended attribute entry node
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0)
[<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0) from [<c01a5670>] (matches_name.clone.22+0xbc/0xd0)
[<c01a5670>] (matches_name.clone.22+0xbc/0xd0) from [<c01a56cc>] (resolve_collision+0x48/0x304)
[<c01a56cc>] (resolve_collision+0x48/0x304) from [<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270)
[<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
	magic          0x6101831
	crc            0xf87567a6
	node_type      0 (inode node)
	group_type     2 (last of node group)
	sqnum          324111858
	len            160
	key            (23300960, inode)
	creat_sqnum    324002935
	size           263248
	nlink          2
	atime          20882.0
	mtime          20884.0
	ctime          20884.0
	uid            0
	gid            0
	mode           16832
	flags          0x1
	xattr_cnt      0
	xattr_size     0
	xattr_names    0
	compr_type     0x0
	data len       0
UBIFS error (pid 4262): ubifs_readdir: cannot find next direntry, error -22
UBIFS assert failed in ubifs_tnc_next_ent at 2776 (pid 4262)
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270)
[<c01a81f0>] (ubifs_tnc_next_ent+0x1c4/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
UBIFS error (pid 4262): ubifs_validate_entry: bad extended attribute entry node
[<c0015efc>] (unwind_backtrace+0x0/0x138) from [<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0)
[<c01a5570>] (lnc_add_directly.clone.21+0x7c/0xc0) from [<c01a5670>] (matches_name.clone.22+0xbc/0xd0)
[<c01a5670>] (matches_name.clone.22+0xbc/0xd0) from [<c01a56cc>] (resolve_collision+0x48/0x304)
[<c01a56cc>] (resolve_collision+0x48/0x304) from [<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270)
[<c01a8174>] (ubifs_tnc_next_ent+0x148/0x270) from [<c0198238>] (ubifs_readdir+0x2e4/0x5a0)
[<c0198238>] (ubifs_readdir+0x2e4/0x5a0) from [<c00bc8e8>] (vfs_readdir+0x90/0xac)
[<c00bc8e8>] (vfs_readdir+0x90/0xac) from [<c00bc9e8>] (sys_getdents+0x74/0xcc)
[<c00bc9e8>] (sys_getdents+0x74/0xcc) from [<c000ebc0>] (ret_fast_syscall+0x0/0x30)
	magic          0x6101831
	crc            0x76707438
	node_type      0 (inode node)
	group_type     2 (last of node group)
	sqnum          324111861
	len            160
	key            (23300960, inode)
	creat_sqnum    324002935
	size           263184
	nlink          2
	atime          20882.0
	mtime          20884.0
	ctime          20884.0
	uid            0
	gid            0
	mode           16832
	flags          0x1
	xattr_cnt      0
	xattr_size     0
	xattr_names    0
	compr_type     0x0
	data len       0
UBIFS error (pid 4262): ubifs_readdir: cannot find next direntry, error -22

Brian


From computersforpeace at gmail.com  Wed Oct 23 22:58:19 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 19:58:19 -0700
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
Message-ID: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>

This patch fixes two memory errors:

1. During a probe failure (in mtd_device_parse_register?) the command
   buffer would not be freed.

2. The command buffer's size is determined based on the 'fast_read'
   boolean, but the assignment of fast_read is made after this
   allocation. Thus, the buffer may be allocated "too small".

To fix the first, just switch to the devres version of kzalloc.

To fix the second, increase MAX_CMD_SIZE unconditionally. It's not worth
saving a byte to fiddle around with the conditions here.

This problem was reported by Yuhang Wang a while back.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Reported-by: Yuhang Wang <wangyuhang2014 at gmail.com>
Cc: <stable at vger.kernel.org>
---
 drivers/mtd/devices/m25p80.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 8d6c87be..63a95ac 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -78,7 +78,7 @@
 
 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
-#define	MAX_CMD_SIZE		5
+#define	MAX_CMD_SIZE		6
 
 #define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
 
@@ -996,15 +996,13 @@ static int m25p_probe(struct spi_device *spi)
 		}
 	}
 
-	flash = kzalloc(sizeof *flash, GFP_KERNEL);
+	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
 	if (!flash)
 		return -ENOMEM;
-	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
-					GFP_KERNEL);
-	if (!flash->command) {
-		kfree(flash);
+
+	flash->command = devm_kzalloc(&spi->dev, MAX_CMD_SIZE, GFP_KERNEL);
+	if (!flash->command)
 		return -ENOMEM;
-	}
 
 	flash->spi = spi;
 	mutex_init(&flash->lock);
@@ -1137,14 +1135,10 @@ static int m25p_probe(struct spi_device *spi)
 static int m25p_remove(struct spi_device *spi)
 {
 	struct m25p	*flash = spi_get_drvdata(spi);
-	int		status;
 
 	/* Clean up MTD stuff. */
-	status = mtd_device_unregister(&flash->mtd);
-	if (status == 0) {
-		kfree(flash->command);
-		kfree(flash);
-	}
+	mtd_device_unregister(&flash->mtd);
+
 	return 0;
 }
 
-- 
1.8.4



From computersforpeace at gmail.com  Wed Oct 23 22:58:20 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 19:58:20 -0700
Subject: [PATCH 2/5] mtd: m25p80: remove obsolete FIXME
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1382583503-13748-2-git-send-email-computersforpeace@gmail.com>

The FIXME and NOTE have already been fixed (we have FAST_READ support).

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/m25p80.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 63a95ac..7c4cbad 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -367,10 +367,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	spi_message_init(&m);
 	memset(t, 0, (sizeof t));
 
-	/* NOTE:
-	 * OPCODE_FAST_READ (if available) is faster.
-	 * Should add 1 byte DUMMY_BYTE.
-	 */
 	t[0].tx_buf = flash->command;
 	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
 	spi_message_add_tail(&t[0], &m);
@@ -388,11 +384,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 		return 1;
 	}
 
-	/* FIXME switch to OPCODE_FAST_READ.  It's required for higher
-	 * clocks; and at this writing, every chip this driver handles
-	 * supports that opcode.
-	 */
-
 	/* Set up the write data buffer. */
 	opcode = flash->read_opcode;
 	flash->command[0] = opcode;
-- 
1.8.4



From computersforpeace at gmail.com  Wed Oct 23 22:58:21 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 19:58:21 -0700
Subject: [PATCH 3/5] mtd: m25p80: re-align ID entries
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1382583503-13748-3-git-send-email-computersforpeace@gmail.com>

No change in the table data.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/m25p80.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c4cbad..7e3ec7a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -740,19 +740,19 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
 
 	/* EON -- en25xxx */
-	{ "en25f32", INFO(0x1c3116, 0, 64 * 1024,  64, SECT_4K) },
-	{ "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
-	{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024,  64, 0) },
-	{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
-	{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
+	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
+	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
+	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
+	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
+	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
+	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
 
 	/* ESMT */
 	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
 
 	/* Everspin */
-	{ "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) },
-	{ "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) },
+	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) },
+	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) },
 
 	/* GigaDevice */
 	{ "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
@@ -777,16 +777,16 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
 
 	/* Micron */
-	{ "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
-	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
-	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
-	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
-	{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
+	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
+	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
+	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
+	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K) },
+	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
 
 	/* PMC */
-	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
-	{ "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
-	{ "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024,  64, SECT_4K) },
+	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
+	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
+	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
 
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
-- 
1.8.4



From computersforpeace at gmail.com  Wed Oct 23 22:58:22 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 19:58:22 -0700
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>

Remove the compile-time option for FAST_READ, since we have run-time
support for detecting it.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/Kconfig  |  7 -------
 drivers/mtd/devices/m25p80.c | 11 ++++++-----
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 74ab4b7..0128138 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -95,13 +95,6 @@ config MTD_M25P80
 	  if you want to specify device partitioning or to use a device which
 	  doesn't support the JEDEC ID instruction.
 
-config M25PXX_USE_FAST_READ
-	bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz"
-	depends on MTD_M25P80
-	default y
-	help
-	  This option enables FAST_READ access supported by ST M25Pxx.
-
 config MTD_SPEAR_SMI
 	tristate "SPEAR MTD NOR Support through SMI controller"
 	depends on PLAT_SPEAR
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7e3ec7a..d6c5c57 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
 	flash->page_size = info->page_size;
 	flash->mtd.writebufsize = flash->page_size;
 
-	flash->fast_read = false;
-	if (np && of_property_read_bool(np, "m25p,fast-read"))
+	if (np)
+		/* If we were instantiated by DT, use it */
+		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
+	else
+		/* If we weren't instantiated by DT, default to fast-read */
 		flash->fast_read = true;
 
-#ifdef CONFIG_M25PXX_USE_FAST_READ
-	flash->fast_read = true;
-#endif
+	/* Some devices cannot do fast-read, no matter what DT tells us */
 	if (info->flags & M25P_NO_FR)
 		flash->fast_read = false;
 
-- 
1.8.4



From computersforpeace at gmail.com  Wed Oct 23 22:58:23 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 23 Oct 2013 19:58:23 -0700
Subject: [PATCH 5/5] mtd: m25p80: remove 'disabled' device check
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>

It seems like the following commit was never necessary

    commit 5f949137952020214cd167093dd7be448f21c079
    Author: Shaohui Xie <Shaohui.Xie at freescale.com>
    Date:   Fri Oct 14 15:49:00 2011 +0800

        mtd: m25p80: don't probe device which has status of 'disabled'

because it duplicates the code in of_platform_device_create_pdata()
which ensures that 'disabled' nodes are never instantiated.

Also, drop the __maybe_unused.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
Cc: Grant Likely <grant.likely at linaro.org>
Cc: Rob Herring <rob.herring at calxeda.com>
Cc: <devicetree at vger.kernel.org>
---
 drivers/mtd/devices/m25p80.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d6c5c57..a1dc49a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -935,12 +935,7 @@ static int m25p_probe(struct spi_device *spi)
 	struct flash_info		*info;
 	unsigned			i;
 	struct mtd_part_parser_data	ppdata;
-	struct device_node __maybe_unused *np = spi->dev.of_node;
-
-#ifdef CONFIG_MTD_OF_PARTS
-	if (!of_device_is_available(np))
-		return -ENODEV;
-#endif
+	struct device_node *np = spi->dev.of_node;
 
 	/* Platform data helps sort out which chip type we have, as
 	 * well as how this board partitions it.  If we don't have
-- 
1.8.4



From sourav.poddar at ti.com  Thu Oct 24 00:51:08 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 10:21:08 +0530
Subject: [PATCH 0/3]Add quad/memory mapped support for SPI flash.
In-Reply-To: <20131024002253.GZ23337@ld-irv-0074.broadcom.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <20131024002253.GZ23337@ld-irv-0074.broadcom.com>
Message-ID: <5268A73C.7020800@ti.com>

Hi Brian,

Thanks for the reply.
On Thursday 24 October 2013 05:52 AM, Brian Norris wrote:
> Hi Sourav,
>
> I must admit, I missed some of this series due to a combination of
> strange Gmail filtering (I just learned that a filter for "PATCH"
> doesn't match "PATCHv3" in Gmail...) and the inconsistent naming in your
> patch series. (I see PATCH, PATCHv3, and RFC/PATCH.) I'll try to prevent
> that in the future.
>
Sorry for this, I tried to keep the tag according to the status of
the patch. I will try to be uniform in my patch subject.
> On Wed, Oct 09, 2013 at 08:54:41PM +0530, Sourav Poddar wrote:
>> This patch add quad/memory mapped support in flash driver(m25p80).
> Does "memory mapped" supoprt need to be in the same series as quad read
> support? Those are very different topics, it seems.
>
Yes, this are different topic and I can send you the quad support
seperately as a single patch ?
>> Added support for quad memory mapped for TI qspi controller also.
>>
>> This patch has been tested with some internal dts data.
> Your patches use new DT bindings which are not documented. If you are
> adding bindings, please document them in
> Documentation/devicetree/bindings/ and CC devicetree at vger.kernel.org.
> (You only need to CC them for the binding documenation, not necessarily
> all your code changes.)
Ok. I will take care of this.
> That being said, I'm not sure you need some of the bindings that you're
> using. I'll comment on the affected patch(es).
>
> Brian



From sourav.poddar at ti.com  Thu Oct 24 01:44:24 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 11:14:24 +0530
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <20131024010619.GA23337@ld-irv-0074.broadcom.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
 <20131024010619.GA23337@ld-irv-0074.broadcom.com>
Message-ID: <5268B3B8.4090807@ti.com>

Hi Brian,

Thanks for the review, my reply inlined.
On Thursday 24 October 2013 06:36 AM, Brian Norris wrote:
> + others
>
> On Wed, Oct 09, 2013 at 08:54:43PM +0530, Sourav Poddar wrote:
>> Some flash also support quad read mode.
>> Adding support for adding quad mode in m25p80
>> for spansion and macronix flash.
>>
>> Signed-off-by: Sourav Poddar<sourav.poddar at ti.com>
>> ---
>> v2->v3:
>> Add macronix flash support
>>   drivers/mtd/devices/m25p80.c |  184 ++++++++++++++++++++++++++++++++++++++++--
>>   1 files changed, 176 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
>> index 26b14f9..dc9bcbf 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
>> @@ -41,6 +41,7 @@
>>   #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
>>   #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
>>   #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
>> +#define	OPCODE_QUAD_READ        0x6b    /* QUAD READ */
>>   #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
>>   #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
>>   #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
>> @@ -48,6 +49,7 @@
>>   #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
>>   #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
>>   #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
>> +#define	OPCODE_RDCR		0x35    /* Read configuration register */
>>
>>   /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
>>   #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
>> @@ -76,6 +78,10 @@
>>   #define	SR_BP2			0x10	/* Block protect 2 */
>>   #define	SR_SRWD			0x80	/* SR write protect */
>>
>> +/* Configuration Register bits. */
>> +#define SPAN_QUAD_CR_EN		0x2	/* Spansion Quad I/O */
>> +#define MACR_QUAD_SR_EN		0x40	/* Macronix Quad I/O */
> Perhaps CR_ can be the prefix, like the status register SR_ macros? So:
>
>    CR_QUAD_EN_SPAN
>    CR_QUAD_EN_MACR
Yes, CR/SR can come as a prefix for Spansion. But, to enable quad mode in
macronix, we need to write to status register. So, things should be like..
   CR_QUAD_EN_SPAN
   SR_QUAD_EN_MACR


>> +
>>   /* Define max times to check status register before we give up. */
>>   #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
>>   #define	MAX_CMD_SIZE		5
>> @@ -95,6 +101,7 @@ struct m25p {
>>   	u8			program_opcode;
>>   	u8			*command;
>>   	bool			fast_read;
>> +	bool			quad_read;
>>   };
>>
>>   static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
>> @@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)
>>   	return spi_write_then_read(flash->spi,&code, 1, NULL, 0);
>>   }
>>
>> +/* Read the configuration register, returning its value in the location
>> + * Return the configuration register value.
>> + * Returns negative if error occurred.
>> +*/
>> +static int read_cr(struct m25p *flash)
>> +{
>> +	u8 code = OPCODE_RDCR;
>> +	int ret;
>> +	u8 val;
>> +
>> +	ret = spi_write_then_read(flash->spi,&code, 1,&val, 1);
>> +	if (ret<  0) {
>> +		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	return val;
>> +}
>> +
>>   /*
>>    * Enable/disable 4-byte addressing mode.
>>    */
>> @@ -336,6 +362,122 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
>>   	return 0;
>>   }
>>
>> +/* Write status register and configuration register with 2 bytes
>> +* The first byte will be written to the status register, while the second byte
>> +* will be written to the configuration register.
>> +* Returns negative if error occurred.
>> +*/
> Not quite the correct multi-line comment style.
>
> /*
>   * It should be something like this. Note the asterisk alignment. You
>   * also could wrap the right edge neatly to nearly 80 characters.
>   */
>
Ok. I will fix this in next version.
>> +static int write_sr_cr(struct m25p *flash, u16 val)
>> +{
>> +	flash->command[0] = OPCODE_WRSR;
>> +	flash->command[1] = val&  0xff;
>> +	flash->command[2] = (val>>  8);
>> +
>> +	return spi_write(flash->spi, flash->command, 3);
>> +}
>> +
>> +static int macronix_quad_enable(struct m25p *flash)
>> +{
>> +	int ret, val;
>> +	u8 cmd[2];
>> +	cmd[0] = OPCODE_WRSR;
>> +
>> +	val = read_sr(flash);
>> +	cmd[1] = val | MACR_QUAD_SR_EN;
>> +	write_enable(flash);
>> +
>> +	spi_write(flash->spi,&cmd, 2);
>> +
>> +	if (wait_till_ready(flash))
>> +		return 1;
>> +
>> +	ret = read_sr(flash);
>> +	if (!(ret>  0&&  (ret&  MACR_QUAD_SR_EN))) {
>> +		dev_err(&flash->spi->dev,
>> +			"Macronix Quad bit not set");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int spansion_quad_enable(struct m25p *flash)
>> +{
>> +	int ret;
>> +	int quad_en = SPAN_QUAD_CR_EN<<  8;
>> +
>> +	write_enable(flash);
>> +
>> +	ret = write_sr_cr(flash, quad_en);
>> +	if (ret<  0) {
>> +		dev_err(&flash->spi->dev,
>> +			"error while writing configuration register");
>> +		return -EINVAL;
>> +	}
>> +
>> +	/* read back and check it */
>> +	ret = read_cr(flash);
>> +	if (!(ret>  0&&  (ret&  SPAN_QUAD_CR_EN))) {
>> +		dev_err(&flash->spi->dev,
>> +			"Spansion Quad bit not set");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
>> +	size_t *retlen, u_char *buf)
>> +{
> This function only has 2 meaningful lines difference from m25p80_read(),
> no? I'd consider combining them. You only need a simple bool/flag to
> tell whether we're in quad mode + you can re-use the 'read_opcode' field
> of struct m25p.
>
Yes, my only motto of keeping a seperate API was that quad supports
different sort of commands, with different dummy cycle requirements.
So, I thought it might get a bit clumsy to handle, if someone later want 
to add a
particular command along with its dummy cycle requirements.

But, yes, you are true, as of now, it can be club into one.

>> +	struct m25p *flash = mtd_to_m25p(mtd);
>> +	struct spi_transfer t[2];
>> +	struct spi_message m;
>> +	uint8_t opcode;
>> +
>> +	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
>> +			__func__, (u32)from, len);
>> +
>> +	spi_message_init(&m);
>> +	memset(t, 0, (sizeof(t)));
>> +
>> +	t[0].tx_buf = flash->command;
>> +	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
> This is the first of 2 lines that are different from m25p80_read(). It
> can easily be combined with the existing read implementation.
>
>> +	spi_message_add_tail(&t[0],&m);
>> +
>> +	t[1].rx_buf = buf;
>> +	t[1].len = len;
>> +	t[1].rx_nbits = SPI_NBITS_QUAD;
> This is the second of 2 different lines. You can change m25p80_read() to
> have something like this:
>
> 	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;
>   
    True, t[0] len can be written as..

     t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 
(flash->fast_read ? 1 : 0));
>> +	spi_message_add_tail(&t[1],&m);
>> +
>> +	mutex_lock(&flash->lock);
>> +
>> +	/* Wait till previous write/erase is done. */
>> +	if (wait_till_ready(flash)) {
>> +		/* REVISIT status return?? */
>> +		mutex_unlock(&flash->lock);
>> +		return 1;
>> +	}
>> +
>> +	/* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
>> +	 * clocks; and at this writing, every chip this driver handles
>> +	 * supports that opcode.
>> +	*/
> What? It seems you blindly copied/edited the already-out-of-date comment
> from m25p80_read().
>
Sorry for this, my bad. I will update this in next version.
>> +
>> +	/* Set up the write data buffer. */
>> +	opcode = flash->read_opcode;
>> +	flash->command[0] = opcode;
>> +	m25p_addr2cmd(flash, from, flash->command);
>> +
>> +	spi_sync(flash->spi,&m);
>> +
>> +	*retlen = m.actual_length - m25p_cmdsz(flash) -
>> +			(flash->quad_read ? 1 : 0);
>> +
>> +	mutex_unlock(&flash->lock);
>> +
>> +	return 0;
>> +}
>> +
>>   /*
>>    * Read an address range from the flash chip.  The address range
>>    * may be any size provided it is within the physical boundaries.
>> @@ -928,6 +1070,7 @@ static int m25p_probe(struct spi_device *spi)
>>   	unsigned			i;
>>   	struct mtd_part_parser_data	ppdata;
>>   	struct device_node __maybe_unused *np = spi->dev.of_node;
>> +	int ret;
>>
>>   #ifdef CONFIG_MTD_OF_PARTS
>>   	if (!of_device_is_available(np))
>> @@ -979,15 +1122,9 @@ static int m25p_probe(struct spi_device *spi)
>>   		}
>>   	}
>>
>> -	flash = kzalloc(sizeof *flash, GFP_KERNEL);
>> +	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
>>   	if (!flash)
>>   		return -ENOMEM;
>> -	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
>> -					GFP_KERNEL);
>> -	if (!flash->command) {
>> -		kfree(flash);
>> -		return -ENOMEM;
>> -	}
> You're combining a bug fix with your feature addition. The size may be
> off-by-one (which is insignificant in this case, I think, but still...)
> so the kmalloc() does needs to move down, but it should be done before
> this feature patch. (Sorry, I've had a patch queued up but didn't send
> it out for a while. I think somebody sorta tried to fix this a while ago
> but didn't send a proper patch.)
>
Yes, true. I can break this patch into two with first patch as the bug 
fix and
second as the feature. Is it ok?
>>
>>   	flash->spi = spi;
>>   	mutex_init(&flash->lock);
>> @@ -1015,7 +1152,6 @@ static int m25p_probe(struct spi_device *spi)
>>   	flash->mtd.flags = MTD_CAP_NORFLASH;
>>   	flash->mtd.size = info->sector_size * info->n_sectors;
>>   	flash->mtd._erase = m25p80_erase;
>> -	flash->mtd._read = m25p80_read;
>>
>>   	/* flash protection support for STmicro chips */
>>   	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ST) {
>> @@ -1067,6 +1203,38 @@ static int m25p_probe(struct spi_device *spi)
>>
>>   	flash->program_opcode = OPCODE_PP;
>>
>> +	flash->quad_read = false;
>> +	if (spi->mode&&  SPI_RX_QUAD)
> You're looking for bitwise '&', not logical'&&'.
>
>> +		flash->quad_read = true;
> But you can just replace the previous 3 lines with:
>
> 	flash->quad_read = spi->mode&  SPI_RX_QUAD;
>
> or this, if you really want be careful about the bit position:
>
> 	flash->quad_read = !!(spi->mode&  SPI_RX_QUAD);
>
True, will fix.
>> +
>> +	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
>> +				(flash->quad_read ? 1 : 0)), GFP_KERNEL);
> That's an ugly conditional. Maybe we just want to increase MAX_CMD_SIZE
> and be done with it? Saving an extra byte is not helping anyone (and I
> think pretty much everyone always has fast_read==true anyway).
Yes, this can be done. But, I was not sure about increasing the macro just
on coding perspective. If it sounds Ok, I will increase the macro and make
the corresponding cleanups.
>> +	if (!flash->command) {
>> +		kfree(flash);
>> +		return -ENOMEM;
>> +	}
>> +
>> +	if (flash->quad_read) {
>> +		if (of_property_read_bool(np, "macronix,quad_enable")) {
> As Jagan mentioned, I think we want this to be discoverable from within
> m25p80.c. I don't think we should require it to be in DT. (We could
> still support a DT binding just in case, but I think the majority
> use-case should be easier to have a flag in the ID table; and if we ever
> support SFDP, that could complement the flag approach nicely.)
>
> Also, be sure to add a documentation patch for the DT binding if you
> really need the binding.
>
>> +			ret = macronix_quad_enable(flash);
>> +			if (ret) {
>> +				dev_err(&spi->dev,
>> +					"error enabling quad");
>> +				return -EINVAL;
>> +			}
>> +		} else if (of_property_read_bool(np, "spansion,quad_enable")) {
> Ditto on the binding. I don't think it's necessary, and I would prefer
> we go with the ID table flag or SFDP. But if you need it, document it.
>
>> +			ret = spansion_quad_enable(flash);
>> +			if (ret) {
>> +				dev_err(&spi->dev,
>> +					"error enabling quad");
>> +				return -EINVAL;
>> +			}
>> +		} else
>> +			dev_dbg(&spi->dev, "quad enable not supported");
> ...and if quad enable is not supported, we just blaze on to use quad
> mode anyway?? No, I think this needs to be rewritten so that we only set
> flash->quad_read = true when all of the following are true:
>
> (1) the SPI controller supports quad I/O
> (2) the flash supports it (i.e., after we see that the device supports
>      it in the ID table/DT/SFDP) and
> (3) we have successfully run one of the quad-enable commands
I got your idea here and to sum up, my below diff can be done to
better clean up the code.

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index f180ffd..6e32f6a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -851,7 +851,7 @@ static const struct spi_device_id m25p_ids[] = {
         { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
         { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
         { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
+       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, MX_QUAD_EN) },

         /* Micron */
         { "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
@@ -870,7 +870,7 @@ static const struct spi_device_id m25p_ids[] = {
         { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
         { "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
+       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 
SP_QUAD_EN) },
         { "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
         { "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
         { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -1094,6 +1094,25 @@ static int m25p_probe(struct spi_device *spi)
         flash->mtd.size = info->sector_size * info->n_sectors;
         flash->mtd._erase = m25p80_erase;

+       if (spi->mode & SPI_RX_QUAD) {
+               if (info->flags & SP_QUAD_EN) {
+                       ret = spansion_quad_enable(flash);
+                       if (ret) {
+                               dev_err(&spi->dev, "error enabling quad");
+                               return -EINVAL;
+                       }
+                       flash->quad_read = true;
+               } else if (info->flags & MX_QUAD_EN) {
+                       ret = spansion_quad_enable(flash);
+                       if (ret) {
+                               dev_err(&spi->dev, "error enabling quad");
+                               return -EINVAL;
+                       }
+                       flash->quad_read = true;
+               } else
+                       dev_dbg(&spi->dev, "quad enable not supported");
+       }
+

> Then if you follow my advice on unifying m25p80_quad_read() and
> m25p80_read(), you'll never have a mismatch between flash->quad_read,
> the state of the flash, and the assigned flash->mtd._read callback
> function. We will trivially fall back to single-I/O read if anything
> fails, too.
>
>> +		flash->mtd._read = m25p80_quad_read;
>> +	} else
>> +		flash->mtd._read = m25p80_read;
> This mtd._read callback assignment should not need to be touched.
Ok, with your above suggestion on clubbing quad with original read 
support, this
will automatically go.
>> +
>>   	if (info->addr_width)
>>   		flash->addr_width = info->addr_width;
>>   	else if (flash->mtd.size>  0x1000000) {
> Brian



From b32955 at freescale.com  Thu Oct 24 02:06:06 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 24 Oct 2013 14:06:06 +0800
Subject: [PATCH for mtd-utils] flash_erase: check the nand type
Message-ID: <1382594766-27467-1-git-send-email-b32955@freescale.com>

Now, the MTD_NANDFLASH stands for SLC nand, and the MTD_MLCNANDFLASH
stands for the MLC nand.

This patch checks the right nand type for the MLC and SLC nand.
And if it is a MLC nand, we do not write cleanmarker for it, only print
out a message to warn the user.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 flash_erase.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/flash_erase.c b/flash_erase.c
index 1421cf9..dd75334 100644
--- a/flash_erase.c
+++ b/flash_erase.c
@@ -184,7 +184,8 @@ int main(int argc, char *argv[])
 
 	eb_start = start / mtd.eb_size;
 
-	isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0;
+	isNAND = (mtd.type == MTD_NANDFLASH || mtd.type == MTD_MLCNANDFLASH)
+			? 1 : 0;
 
 	if (jffs2) {
 		cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
@@ -272,6 +273,12 @@ int main(int argc, char *argv[])
 
 		/* write cleanmarker */
 		if (isNAND) {
+			if (mtd.type == MTD_MLCNANDFLASH) {
+				sys_errmsg("%s: we can't write the cleanmarker "
+					"for the MLC nand.", mtd_device);
+				continue;
+			}
+
 			if (mtd_write_oob(mtd_desc, &mtd, fd, (uint64_t)offset + clmpos, clmlen, &cleanmarker) != 0) {
 				sys_errmsg("%s: MTD writeoob failure", mtd_device);
 				continue;
-- 
1.7.2.rc3




From thanos at stargate-vortex.com  Thu Oct 24 01:37:43 2013
From: thanos at stargate-vortex.com (anthonyna)
Date: Thu, 24 Oct 2013 07:37:43 +0200
Subject: =?koi8-r?Q?=FC=D4=CF_=D7=CE=D1=D4=CE=CF?=
Message-ID: <20131024061334.0AD5326D65@svrmail01.thanos.ch>

99kg2sHQ0s/T1M8g09XNxcXUxSDOwcjPxMnU2CDR2tnLINMg19PRy8nNIN7V1sXaxc3Dxc0gaHR0
cDovL3d3dy5oYW1lYXUtZGUta2VyeWFyZ29uLmNvbS90bXAvempmbXUuaHRtDQo=


From b32955 at freescale.com  Thu Oct 24 02:59:58 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 24 Oct 2013 14:59:58 +0800
Subject: [PATCH] mtd: gpmi: fix the ecc regression
In-Reply-To: <20131022185639.GK23337@ld-irv-0074.broadcom.com>
References: <1382418628-4521-1-git-send-email-b32955@freescale.com>
 <20131022185639.GK23337@ld-irv-0074.broadcom.com>
Message-ID: <5268C56E.8050806@freescale.com>

Hi David & Mark & Brian:

    thanks for your review and comments.
> ... so why don't you just add a DT property to actually specify the ECC
> selection itself, rather than indirectly specifying it through a vague
Do you mean i should add a DT property like "fsl, gpmi-use-new-ecclayout" ?

I am not understand "the ECC selection itself".



thanks
Huang Shijie





From computersforpeace at gmail.com  Thu Oct 24 03:34:00 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 00:34:00 -0700
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <5268B3B8.4090807@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
 <20131024010619.GA23337@ld-irv-0074.broadcom.com>
 <5268B3B8.4090807@ti.com>
Message-ID: <20131024073400.GA9863@norris.computersforpeace.net>

On Thu, Oct 24, 2013 at 11:14:24AM +0530, Sourav Poddar wrote:
> On Thursday 24 October 2013 06:36 AM, Brian Norris wrote:
> >On Wed, Oct 09, 2013 at 08:54:43PM +0530, Sourav Poddar wrote:
> >>--- a/drivers/mtd/devices/m25p80.c
> >>+++ b/drivers/mtd/devices/m25p80.c
> >>@@ -76,6 +78,10 @@
> >>  #define	SR_BP2			0x10	/* Block protect 2 */
> >>  #define	SR_SRWD			0x80	/* SR write protect */
> >>
> >>+/* Configuration Register bits. */
> >>+#define SPAN_QUAD_CR_EN		0x2	/* Spansion Quad I/O */
> >>+#define MACR_QUAD_SR_EN		0x40	/* Macronix Quad I/O */
> >Perhaps CR_ can be the prefix, like the status register SR_ macros? So:
> >
> >   CR_QUAD_EN_SPAN
> >   CR_QUAD_EN_MACR
> Yes, CR/SR can come as a prefix for Spansion. But, to enable quad mode in
> macronix, we need to write to status register. So, things should be like..
>   CR_QUAD_EN_SPAN
>   SR_QUAD_EN_MACR

Yes, I missed the CR vs. SR. My bad.

> >>+
> >>  /* Define max times to check status register before we give up. */
> >>  #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
> >>  #define	MAX_CMD_SIZE		5
> >>@@ -95,6 +101,7 @@ struct m25p {
> >>@@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)

...

> >>+static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
> >>+	size_t *retlen, u_char *buf)
> >>+{
> >This function only has 2 meaningful lines difference from m25p80_read(),
> >no? I'd consider combining them. You only need a simple bool/flag to
> >tell whether we're in quad mode + you can re-use the 'read_opcode' field
> >of struct m25p.
> >
> Yes, my only motto of keeping a seperate API was that quad supports
> different sort of commands, with different dummy cycle requirements.
> So, I thought it might get a bit clumsy to handle, if someone later
> want to add a
> particular command along with its dummy cycle requirements.
> 
> But, yes, you are true, as of now, it can be club into one.
> 
> >>+	struct m25p *flash = mtd_to_m25p(mtd);
> >>+	struct spi_transfer t[2];
> >>+	struct spi_message m;
> >>+	uint8_t opcode;
> >>+
> >>+	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
> >>+			__func__, (u32)from, len);
> >>+
> >>+	spi_message_init(&m);
> >>+	memset(t, 0, (sizeof(t)));
> >>+
> >>+	t[0].tx_buf = flash->command;
> >>+	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
> >This is the first of 2 lines that are different from m25p80_read(). It
> >can easily be combined with the existing read implementation.
> >
> >>+	spi_message_add_tail(&t[0],&m);
> >>+
> >>+	t[1].rx_buf = buf;
> >>+	t[1].len = len;
> >>+	t[1].rx_nbits = SPI_NBITS_QUAD;
> >This is the second of 2 different lines. You can change m25p80_read() to
> >have something like this:
> >
> >	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;
>    True, t[0] len can be written as..
> 
>     t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 :
> (flash->fast_read ? 1 : 0));

Yikes. I'd go easy with the embedded '?:' operators.

If you're going for really fun ways to shorten things, though, you can
do:

        t[0].len = m25p_cmdsz(flash) + !!(flash->quad_read || flash->fast_read);

But seriously, I think it may be better to be more verbose to make it 
clearer. Like:

	t[0].len = m25p_cmdsz(flash);
	/* Dummy cycle */
	if (flash->quad_read || flash->fast_read)
		t[0].len++;

If you're really looking at making dummy cycles more modular, though, 
you can add an extra function like this:

static inline int m25p80_dummy_cycles_read(struct m25p *flash)
{
	if (flash->quad_read || flash->fast_read)
		return 1;
	return 0;
}

Then it's:

	t[0].len = m25p_cmdsz(flash) + m25p80_dummy_cycles_read(flash);

Then you can convert this to represent the # of bits of dummy cycle if
you ever do more exotic commands and implement a proper SPI dummy cycle
API.

But please, don't just embed a bunch of '?:'.

> >>+	spi_message_add_tail(&t[1],&m);
> >>+
> >>+	mutex_lock(&flash->lock);
> >>+
> >>+	/* Wait till previous write/erase is done. */
> >>+	if (wait_till_ready(flash)) {
> >>+		/* REVISIT status return?? */
> >>+		mutex_unlock(&flash->lock);
> >>+		return 1;
> >>+	}
> >>+
> >>+	/* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
> >>+	 * clocks; and at this writing, every chip this driver handles
> >>+	 * supports that opcode.
> >>+	*/
> >What? It seems you blindly copied/edited the already-out-of-date comment
> >from m25p80_read().
> >
> Sorry for this, my bad. I will update this in next version.
> >>+
> >>+	/* Set up the write data buffer. */
> >>+	opcode = flash->read_opcode;
> >>+	flash->command[0] = opcode;
> >>+	m25p_addr2cmd(flash, from, flash->command);
> >>+
> >>+	spi_sync(flash->spi,&m);
> >>+
> >>+	*retlen = m.actual_length - m25p_cmdsz(flash) -
> >>+			(flash->quad_read ? 1 : 0);
> >>+
> >>+	mutex_unlock(&flash->lock);
> >>+
> >>+	return 0;
> >>+}
> >>+
> >>  /*
> >>   * Read an address range from the flash chip.  The address range
> >>   * may be any size provided it is within the physical boundaries.
> >>@@ -979,15 +1122,9 @@ static int m25p_probe(struct spi_device *spi)
> >>  		}
> >>  	}
> >>
> >>-	flash = kzalloc(sizeof *flash, GFP_KERNEL);
> >>+	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
> >>  	if (!flash)
> >>  		return -ENOMEM;
> >>-	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
> >>-					GFP_KERNEL);
> >>-	if (!flash->command) {
> >>-		kfree(flash);
> >>-		return -ENOMEM;
> >>-	}
> >You're combining a bug fix with your feature addition. The size may be
> >off-by-one (which is insignificant in this case, I think, but still...)
> >so the kmalloc() does needs to move down, but it should be done before
> >this feature patch. (Sorry, I've had a patch queued up but didn't send
> >it out for a while. I think somebody sorta tried to fix this a while ago
> >but didn't send a proper patch.)
> >
> Yes, true. I can break this patch into two with first patch as the
> bug fix and
> second as the feature. Is it ok?

I just submitted my cleanups which (among other things) fixes this bug.
I believe I CC'd you. Go ahead and review it, and if it works to your
liking, please just base your work on top of it. I'll apply some or all
of that series if no one objects.

> >>
> >>  	flash->spi = spi;
> >>  	mutex_init(&flash->lock);
> >>@@ -1067,6 +1203,38 @@ static int m25p_probe(struct spi_device *spi)
> >>
> >>  	flash->program_opcode = OPCODE_PP;
> >>
> >>+	flash->quad_read = false;
> >>+	if (spi->mode&&  SPI_RX_QUAD)
> >You're looking for bitwise '&', not logical'&&'.
> >
> >>+		flash->quad_read = true;
> >But you can just replace the previous 3 lines with:
> >
> >	flash->quad_read = spi->mode&  SPI_RX_QUAD;
> >
> >or this, if you really want be careful about the bit position:
> >
> >	flash->quad_read = !!(spi->mode&  SPI_RX_QUAD);
> >
> True, will fix.
> >>+
> >>+	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
> >>+				(flash->quad_read ? 1 : 0)), GFP_KERNEL);
> >That's an ugly conditional. Maybe we just want to increase MAX_CMD_SIZE
> >and be done with it? Saving an extra byte is not helping anyone (and I
> >think pretty much everyone always has fast_read==true anyway).
> Yes, this can be done. But, I was not sure about increasing the macro just
> on coding perspective. If it sounds Ok, I will increase the macro and make
> the corresponding cleanups.

Just take a look at my patch for this issue, please.

> >>+		if (of_property_read_bool(np, "macronix,quad_enable")) {
...
> >>+		} else if (of_property_read_bool(np, "spansion,quad_enable")) {
...
> >>+		} else
> >>+			dev_dbg(&spi->dev, "quad enable not supported");
> >...and if quad enable is not supported, we just blaze on to use quad
> >mode anyway?? No, I think this needs to be rewritten so that we only set
> >flash->quad_read = true when all of the following are true:
> >
> >(1) the SPI controller supports quad I/O
> >(2) the flash supports it (i.e., after we see that the device supports
> >     it in the ID table/DT/SFDP) and
> >(3) we have successfully run one of the quad-enable commands
> I got your idea here and to sum up, my below diff can be done to
> better clean up the code.

Looks a little better. A few comments on it below.

> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index f180ffd..6e32f6a 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -851,7 +851,7 @@ static const struct spi_device_id m25p_ids[] = {
>         { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>         { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>         { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
> -       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
> +       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, MX_QUAD_EN) },

I don't think we need a separate Macronix and Spansion quad flag; I
think we can get by with just a M25P_QUAD flag (or some other name like
that). We can differentiate MXIC and Spansion via just the manufacturer
by it's ID, right? (See the similarity to set_4byte().)

Do all parts that support quad read also support all the other quad
opcodes (like quad program)?

> 
>         /* Micron */
>         { "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
> @@ -870,7 +870,7 @@ static const struct spi_device_id m25p_ids[] = {
>         { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
>         { "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
>         { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
> -       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
> +       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512,
> SP_QUAD_EN) },
>         { "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
>         { "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>         { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
> @@ -1094,6 +1094,25 @@ static int m25p_probe(struct spi_device *spi)
>         flash->mtd.size = info->sector_size * info->n_sectors;
>         flash->mtd._erase = m25p80_erase;
> 
> +       if (spi->mode & SPI_RX_QUAD) {
> +               if (info->flags & SP_QUAD_EN) {
> +                       ret = spansion_quad_enable(flash);
> +                       if (ret) {
> +                               dev_err(&spi->dev, "error enabling quad");
> +                               return -EINVAL;
> +                       }
> +                       flash->quad_read = true;
> +               } else if (info->flags & MX_QUAD_EN) {
> +                       ret = spansion_quad_enable(flash);
> +                       if (ret) {
> +                               dev_err(&spi->dev, "error enabling quad");
> +                               return -EINVAL;
> +                       }
> +                       flash->quad_read = true;
> +               } else
> +                       dev_dbg(&spi->dev, "quad enable not supported");
> +       }
> +

I think we'll want a separate function set_quad_mode(), so we can just do:

	if (spi->mode & SPI_RX_QUAD && info->flags & M25P_QUAD) {
		ret = set_quad_mode(flash, info->jedec_id, 1);
		if (ret) {
			dev_err(...);
			return ret;
		}
		flash->quad_read = true;
	}

Then the set_quad_mode() function can do things very similarly to
set_4byte(), based on the manufacturer JEDEC ID.

Do you plan on supporting Quad Page Program? How about the dedicated
4-byte addressing variants of these Quad commands?

Are there any other important side effects when enabling quad mode? I'm
reading some things about changes in WP# and HOLD# behavior, but I'm not
quite sure right now if that has ramifications on the rest of the
driver.

Brian


From computersforpeace at gmail.com  Thu Oct 24 03:52:49 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 00:52:49 -0700
Subject: [PATCH] mtd: gpmi: fix the ecc regression
In-Reply-To: <5268C56E.8050806@freescale.com>
References: <1382418628-4521-1-git-send-email-b32955@freescale.com>
 <20131022185639.GK23337@ld-irv-0074.broadcom.com>
 <5268C56E.8050806@freescale.com>
Message-ID: <20131024075249.GB9863@norris.computersforpeace.net>

On Thu, Oct 24, 2013 at 02:59:58PM +0800, Huang Shijie wrote:
> Hi David & Mark & Brian:
> 
>    thanks for your review and comments.
> >... so why don't you just add a DT property to actually specify the ECC
> >selection itself, rather than indirectly specifying it through a vague
> Do you mean i should add a DT property like "fsl, gpmi-use-new-ecclayout" ?
> 
> I am not understand "the ECC selection itself".

Sorry if that was unclear. I was recommending that the DT property
actually specify what the properties of the ECC layout were. Like ECC
strength (as an integer). Or spare area/step size/whatever else needed
to specify what these legacy and new layouts actually are. Your binding
was too vague; it wasn't describing what the layout is.

David seemed to suggest that something like your current binding might
be OK. (I still thing it was too vague, but if you can describe it
better, it may be sufficient.) A possible starting point:
"fsl,use-minimum-ecc". Does this properly reflect your intention of
using the datasheet's minimum required ECC (from ONFI or from the
driver's full ID table)?

But all that beside, I think your first priority is to fix the
regression for the current release cycle. I'm not keen on trying to
agree on a good DT binding and get it merged immediately.

Can you resend in two patches? The first one will default to using
legacy_set_geometry() to retain the old behavior and prevent
regressions. The second one can add a DT binding to re-introduce support
for your new layout. That way we can take the first one with no
question, and the second one can be taken when it's ready: either for
3.12 or 3.13.

Brian


From computersforpeace at gmail.com  Thu Oct 24 04:00:41 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 01:00:41 -0700
Subject: [PATCH for mtd-utils] flash_erase: check the nand type
In-Reply-To: <1382594766-27467-1-git-send-email-b32955@freescale.com>
References: <1382594766-27467-1-git-send-email-b32955@freescale.com>
Message-ID: <20131024080041.GC9863@norris.computersforpeace.net>

On Thu, Oct 24, 2013 at 02:06:06PM +0800, Huang Shijie wrote:
> Now, the MTD_NANDFLASH stands for SLC nand, and the MTD_MLCNANDFLASH
> stands for the MLC nand.
> 
> This patch checks the right nand type for the MLC and SLC nand.
> And if it is a MLC nand, we do not write cleanmarker for it, only print
> out a message to warn the user.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
>  flash_erase.c |    9 ++++++++-
>  1 files changed, 8 insertions(+), 1 deletions(-)
> 
> diff --git a/flash_erase.c b/flash_erase.c
> index 1421cf9..dd75334 100644
> --- a/flash_erase.c
> +++ b/flash_erase.c
> @@ -184,7 +184,8 @@ int main(int argc, char *argv[])
>  
>  	eb_start = start / mtd.eb_size;
>  
> -	isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0;
> +	isNAND = (mtd.type == MTD_NANDFLASH || mtd.type == MTD_MLCNANDFLASH)
> +			? 1 : 0;

Perhaps you can #include <stdbool.h> and make 'isNAND' into a proper
bool variable? Then this becomes:

	isNAND = mtd.type == MTD_NANDFLASH || mtd.type == MTD_MLCNANDFLASH;

>  
>  	if (jffs2) {
>  		cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
> @@ -272,6 +273,12 @@ int main(int argc, char *argv[])
>  
>  		/* write cleanmarker */
>  		if (isNAND) {
> +			if (mtd.type == MTD_MLCNANDFLASH) {
> +				sys_errmsg("%s: we can't write the cleanmarker "
> +					"for the MLC nand.", mtd_device);
> +				continue;
> +			}
> +

This is in a loop. This will print the same message repeatedly if you
are erasing/marking an entire partition. Please test your changes before
sending v2.

You could probably just error out (or warn) like the following.

diff --git a/flash_erase.c b/flash_erase.c
index 1421cf9..0e385e9 100644
--- a/flash_erase.c
+++ b/flash_erase.c
@@ -169,6 +169,9 @@ int main(int argc, char *argv[])
 	if (error)
 		return errmsg("Try `--help' for more information");
 
+	if (jffs2 && mtd.type == MTD_MLCNANDFLASH)
+		return errmsg("JFFS2 cannot support MLC NAND");
+
 	/*
 	 * Locate MTD and prepare for erasure
 	 */

>  			if (mtd_write_oob(mtd_desc, &mtd, fd, (uint64_t)offset + clmpos, clmlen, &cleanmarker) != 0) {
>  				sys_errmsg("%s: MTD writeoob failure", mtd_device);
>  				continue;

Brian


From b32955 at freescale.com  Thu Oct 24 04:14:44 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 24 Oct 2013 16:14:44 +0800
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
Message-ID: <1382602484-12023-1-git-send-email-b32955@freescale.com>

The legacy ecc layout is to use all the OOB area by computing the ecc strength
and ecc step size ourselves.

The patch "2febcdf mtd: gpmi: set the BCHs geometry with the ecc info"
makes the gpmi to use the ECC info(ecc strength and ecc step size)
provided by the MTD code, and creates a different NAND ecc layout
for the BCH , and use the new ecc layout, this brings a regression to us:
   We can not mount the ubifs which was created by the old NAND ecc layout.

This patch fixes this issue by use the legacy ecc layout firstly, if it fails
we try to use the new ecc layout.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
Cc: stable at vger.kernel.org
---
v1 --> v2:
	[0] remove the DT binding.
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 6807d7c..f9ee7e5 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -352,7 +352,7 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
-	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
+	return legacy_set_geometry(this) ? set_geometry_by_ecc_info(this) : 0;
 }
 
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
-- 
1.7.2.rc3




From b32955 at freescale.com  Thu Oct 24 04:38:38 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 24 Oct 2013 16:38:38 +0800
Subject: [PATCH] mtd: gpmi: fix the ecc regression
In-Reply-To: <20131024075249.GB9863@norris.computersforpeace.net>
References: <1382418628-4521-1-git-send-email-b32955@freescale.com>
 <20131022185639.GK23337@ld-irv-0074.broadcom.com>
 <5268C56E.8050806@freescale.com>
 <20131024075249.GB9863@norris.computersforpeace.net>
Message-ID: <5268DC8E.1040908@freescale.com>

? 2013?10?24? 15:52, Brian Norris ??:
> David seemed to suggest that something like your current binding might
> be OK. (I still thing it was too vague, but if you can describe it
> better, it may be sufficient.) A possible starting point:
> "fsl,use-minimum-ecc". Does this properly reflect your intention of
> using the datasheet's minimum required ECC (from ONFI or from the
> driver's full ID table)?
yes, it's okay to me.

thanks
Huang Shijie



From sourav.poddar at ti.com  Thu Oct 24 04:44:59 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:14:59 +0530
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <20131024073400.GA9863@norris.computersforpeace.net>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
 <20131024010619.GA23337@ld-irv-0074.broadcom.com> <5268B3B8.4090807@ti.com>
 <20131024073400.GA9863@norris.computersforpeace.net>
Message-ID: <5268DE0B.7040208@ti.com>

Hi Brian,
On Thursday 24 October 2013 01:04 PM, Brian Norris wrote:
> On Thu, Oct 24, 2013 at 11:14:24AM +0530, Sourav Poddar wrote:
>> On Thursday 24 October 2013 06:36 AM, Brian Norris wrote:
>>> On Wed, Oct 09, 2013 at 08:54:43PM +0530, Sourav Poddar wrote:
>>>> --- a/drivers/mtd/devices/m25p80.c
>>>> +++ b/drivers/mtd/devices/m25p80.c
>>>> @@ -76,6 +78,10 @@
>>>>   #define	SR_BP2			0x10	/* Block protect 2 */
>>>>   #define	SR_SRWD			0x80	/* SR write protect */
>>>>
>>>> +/* Configuration Register bits. */
>>>> +#define SPAN_QUAD_CR_EN		0x2	/* Spansion Quad I/O */
>>>> +#define MACR_QUAD_SR_EN		0x40	/* Macronix Quad I/O */
>>> Perhaps CR_ can be the prefix, like the status register SR_ macros? So:
>>>
>>>    CR_QUAD_EN_SPAN
>>>    CR_QUAD_EN_MACR
>> Yes, CR/SR can come as a prefix for Spansion. But, to enable quad mode in
>> macronix, we need to write to status register. So, things should be like..
>>    CR_QUAD_EN_SPAN
>>    SR_QUAD_EN_MACR
> Yes, I missed the CR vs. SR. My bad.
>
>>>> +
>>>>   /* Define max times to check status register before we give up. */
>>>>   #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
>>>>   #define	MAX_CMD_SIZE		5
>>>> @@ -95,6 +101,7 @@ struct m25p {
>>>> @@ -163,6 +170,25 @@ static inline int write_disable(struct m25p *flash)
> ...
>
>>>> +static int m25p80_quad_read(struct mtd_info *mtd, loff_t from, size_t len,
>>>> +	size_t *retlen, u_char *buf)
>>>> +{
>>> This function only has 2 meaningful lines difference from m25p80_read(),
>>> no? I'd consider combining them. You only need a simple bool/flag to
>>> tell whether we're in quad mode + you can re-use the 'read_opcode' field
>>> of struct m25p.
>>>
>> Yes, my only motto of keeping a seperate API was that quad supports
>> different sort of commands, with different dummy cycle requirements.
>> So, I thought it might get a bit clumsy to handle, if someone later
>> want to add a
>> particular command along with its dummy cycle requirements.
>>
>> But, yes, you are true, as of now, it can be club into one.
>>
>>>> +	struct m25p *flash = mtd_to_m25p(mtd);
>>>> +	struct spi_transfer t[2];
>>>> +	struct spi_message m;
>>>> +	uint8_t opcode;
>>>> +
>>>> +	pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev),
>>>> +			__func__, (u32)from, len);
>>>> +
>>>> +	spi_message_init(&m);
>>>> +	memset(t, 0, (sizeof(t)));
>>>> +
>>>> +	t[0].tx_buf = flash->command;
>>>> +	t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 : 0);
>>> This is the first of 2 lines that are different from m25p80_read(). It
>>> can easily be combined with the existing read implementation.
>>>
>>>> +	spi_message_add_tail(&t[0],&m);
>>>> +
>>>> +	t[1].rx_buf = buf;
>>>> +	t[1].len = len;
>>>> +	t[1].rx_nbits = SPI_NBITS_QUAD;
>>> This is the second of 2 different lines. You can change m25p80_read() to
>>> have something like this:
>>>
>>> 	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;
>>     True, t[0] len can be written as..
>>
>>      t[0].len = m25p_cmdsz(flash) + (flash->quad_read ? 1 :
>> (flash->fast_read ? 1 : 0));
> Yikes. I'd go easy with the embedded '?:' operators.
>
> If you're going for really fun ways to shorten things, though, you can
> do:
>
>          t[0].len = m25p_cmdsz(flash) + !!(flash->quad_read || flash->fast_read);
>
> But seriously, I think it may be better to be more verbose to make it
> clearer. Like:
>
> 	t[0].len = m25p_cmdsz(flash);
> 	/* Dummy cycle */
> 	if (flash->quad_read || flash->fast_read)
> 		t[0].len++;
>
> If you're really looking at making dummy cycles more modular, though,
> you can add an extra function like this:
>
> static inline int m25p80_dummy_cycles_read(struct m25p *flash)
> {
> 	if (flash->quad_read || flash->fast_read)
> 		return 1;
> 	return 0;
> }
>
> Then it's:
>
> 	t[0].len = m25p_cmdsz(flash) + m25p80_dummy_cycles_read(flash);
>
> Then you can convert this to represent the # of bits of dummy cycle if
> you ever do more exotic commands and implement a proper SPI dummy cycle
> API.
>
> But please, don't just embed a bunch of '?:'.
>
The above suggestion looks quite clean and verbose. I will go this way in my
next version.
>>>> +	spi_message_add_tail(&t[1],&m);
>>>> +
>>>> +	mutex_lock(&flash->lock);
>>>> +
>>>> +	/* Wait till previous write/erase is done. */
>>>> +	if (wait_till_ready(flash)) {
>>>> +		/* REVISIT status return?? */
>>>> +		mutex_unlock(&flash->lock);
>>>> +		return 1;
>>>> +	}
>>>> +
>>>> +	/* FIXME switch to OPCODE_QUAD_READ.  It's required for higher
>>>> +	 * clocks; and at this writing, every chip this driver handles
>>>> +	 * supports that opcode.
>>>> +	*/
>>> What? It seems you blindly copied/edited the already-out-of-date comment
>> >from m25p80_read().
>> Sorry for this, my bad. I will update this in next version.
>>>> +
>>>> +	/* Set up the write data buffer. */
>>>> +	opcode = flash->read_opcode;
>>>> +	flash->command[0] = opcode;
>>>> +	m25p_addr2cmd(flash, from, flash->command);
>>>> +
>>>> +	spi_sync(flash->spi,&m);
>>>> +
>>>> +	*retlen = m.actual_length - m25p_cmdsz(flash) -
>>>> +			(flash->quad_read ? 1 : 0);
>>>> +
>>>> +	mutex_unlock(&flash->lock);
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>   /*
>>>>    * Read an address range from the flash chip.  The address range
>>>>    * may be any size provided it is within the physical boundaries.
>>>> @@ -979,15 +1122,9 @@ static int m25p_probe(struct spi_device *spi)
>>>>   		}
>>>>   	}
>>>>
>>>> -	flash = kzalloc(sizeof *flash, GFP_KERNEL);
>>>> +	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
>>>>   	if (!flash)
>>>>   		return -ENOMEM;
>>>> -	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
>>>> -					GFP_KERNEL);
>>>> -	if (!flash->command) {
>>>> -		kfree(flash);
>>>> -		return -ENOMEM;
>>>> -	}
>>> You're combining a bug fix with your feature addition. The size may be
>>> off-by-one (which is insignificant in this case, I think, but still...)
>>> so the kmalloc() does needs to move down, but it should be done before
>>> this feature patch. (Sorry, I've had a patch queued up but didn't send
>>> it out for a while. I think somebody sorta tried to fix this a while ago
>>> but didn't send a proper patch.)
>>>
>> Yes, true. I can break this patch into two with first patch as the
>> bug fix and
>> second as the feature. Is it ok?
> I just submitted my cleanups which (among other things) fixes this bug.
> I believe I CC'd you. Go ahead and review it, and if it works to your
> liking, please just base your work on top of it. I'll apply some or all
> of that series if no one objects.
>
Ok.
>>>>   	flash->spi = spi;
>>>>   	mutex_init(&flash->lock);
>>>> @@ -1067,6 +1203,38 @@ static int m25p_probe(struct spi_device *spi)
>>>>
>>>>   	flash->program_opcode = OPCODE_PP;
>>>>
>>>> +	flash->quad_read = false;
>>>> +	if (spi->mode&&   SPI_RX_QUAD)
>>> You're looking for bitwise '&', not logical'&&'.
>>>
>>>> +		flash->quad_read = true;
>>> But you can just replace the previous 3 lines with:
>>>
>>> 	flash->quad_read = spi->mode&   SPI_RX_QUAD;
>>>
>>> or this, if you really want be careful about the bit position:
>>>
>>> 	flash->quad_read = !!(spi->mode&   SPI_RX_QUAD);
>>>
>> True, will fix.
>>>> +
>>>> +	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 :
>>>> +				(flash->quad_read ? 1 : 0)), GFP_KERNEL);
>>> That's an ugly conditional. Maybe we just want to increase MAX_CMD_SIZE
>>> and be done with it? Saving an extra byte is not helping anyone (and I
>>> think pretty much everyone always has fast_read==true anyway).
>> Yes, this can be done. But, I was not sure about increasing the macro just
>> on coding perspective. If it sounds Ok, I will increase the macro and make
>> the corresponding cleanups.
> Just take a look at my patch for this issue, please.
>
Ok.
>>>> +		if (of_property_read_bool(np, "macronix,quad_enable")) {
> ...
>>>> +		} else if (of_property_read_bool(np, "spansion,quad_enable")) {
> ...
>>>> +		} else
>>>> +			dev_dbg(&spi->dev, "quad enable not supported");
>>> ...and if quad enable is not supported, we just blaze on to use quad
>>> mode anyway?? No, I think this needs to be rewritten so that we only set
>>> flash->quad_read = true when all of the following are true:
>>>
>>> (1) the SPI controller supports quad I/O
>>> (2) the flash supports it (i.e., after we see that the device supports
>>>      it in the ID table/DT/SFDP) and
>>> (3) we have successfully run one of the quad-enable commands
>> I got your idea here and to sum up, my below diff can be done to
>> better clean up the code.
> Looks a little better. A few comments on it below.
>
>> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
>> index f180ffd..6e32f6a 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
>> @@ -851,7 +851,7 @@ static const struct spi_device_id m25p_ids[] = {
>>          { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>>          { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>>          { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
>> -       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
>> +       { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, MX_QUAD_EN) },
> I don't think we need a separate Macronix and Spansion quad flag; I
> think we can get by with just a M25P_QUAD flag (or some other name like
> that). We can differentiate MXIC and Spansion via just the manufacturer
> by it's ID, right? (See the similarity to set_4byte().)
>
Yes, I believe this can be done on similar lines to set_4byte. I will try
this out in my next version.


> Do all parts that support quad read also support all the other quad
> opcodes (like quad program)?
>
I have Spansion and Macronix flash with me.

For spansion,
supported quad commands are:
QOR(0x6b) which is what I am using.
QIOR(0xeb)
DDR QIOR(0xed)

For macronix,
QOR(0x6b) which is what I am using.
QIOR(0xeb)

>>          /* Micron */
>>          { "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
>> @@ -870,7 +870,7 @@ static const struct spi_device_id m25p_ids[] = {
>>          { "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
>>          { "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
>>          { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
>> -       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
>> +       { "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512,
>> SP_QUAD_EN) },
>>          { "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
>>          { "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>>          { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
>> @@ -1094,6 +1094,25 @@ static int m25p_probe(struct spi_device *spi)
>>          flash->mtd.size = info->sector_size * info->n_sectors;
>>          flash->mtd._erase = m25p80_erase;
>>
>> +       if (spi->mode&  SPI_RX_QUAD) {
>> +               if (info->flags&  SP_QUAD_EN) {
>> +                       ret = spansion_quad_enable(flash);
>> +                       if (ret) {
>> +                               dev_err(&spi->dev, "error enabling quad");
>> +                               return -EINVAL;
>> +                       }
>> +                       flash->quad_read = true;
>> +               } else if (info->flags&  MX_QUAD_EN) {
>> +                       ret = spansion_quad_enable(flash);
>> +                       if (ret) {
>> +                               dev_err(&spi->dev, "error enabling quad");
>> +                               return -EINVAL;
>> +                       }
>> +                       flash->quad_read = true;
>> +               } else
>> +                       dev_dbg(&spi->dev, "quad enable not supported");
>> +       }
>> +
> I think we'll want a separate function set_quad_mode(), so we can just do:
>
> 	if (spi->mode&  SPI_RX_QUAD&&  info->flags&  M25P_QUAD) {
> 		ret = set_quad_mode(flash, info->jedec_id, 1);
> 		if (ret) {
> 			dev_err(...);
> 			return ret;
> 		}
> 		flash->quad_read = true;
> 	}
>
> Then the set_quad_mode() function can do things very similarly to
> set_4byte(), based on the manufacturer JEDEC ID.
Make sense, I will implement this.
> Do you plan on supporting Quad Page Program?
Currently, I am planning to add Quad output read(8 dummy cycle) only.
>   How about the dedicated
> 4-byte addressing variants of these Quad commands?
>
Hmm, seems like I missed this. I will add this.
> Are there any other important side effects when enabling quad mode? I'm
> reading some things about changes in WP# and HOLD# behavior, but I'm not
> quite sure right now if that has ramifications on the rest of the
> driver.
>
Nope, I have not faced any. WP# and HOLD# are the IO2 and IO3 lines
respectively in quad mode.
> Brian



From sourav.poddar at ti.com  Thu Oct 24 05:00:50 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:30:50 +0530
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <5268E1C2.3030202@ti.com>

On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
> This patch fixes two memory errors:
>
> 1. During a probe failure (in mtd_device_parse_register?) the command
>     buffer would not be freed.
>
> 2. The command buffer's size is determined based on the 'fast_read'
>     boolean, but the assignment of fast_read is made after this
>     allocation. Thus, the buffer may be allocated "too small".
>
> To fix the first, just switch to the devres version of kzalloc.
>
> To fix the second, increase MAX_CMD_SIZE unconditionally. It's not worth
> saving a byte to fiddle around with the conditions here.
>
> This problem was reported by Yuhang Wang a while back.
>
> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
> Reported-by: Yuhang Wang<wangyuhang2014 at gmail.com>
> Cc:<stable at vger.kernel.org>
Reviewed-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
>   drivers/mtd/devices/m25p80.c | 20 +++++++-------------
>   1 file changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 8d6c87be..63a95ac 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -78,7 +78,7 @@
>
>   /* Define max times to check status register before we give up. */
>   #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
> -#define	MAX_CMD_SIZE		5
> +#define	MAX_CMD_SIZE		6
>
>   #define JEDEC_MFR(_jedec_id)	((_jedec_id)>>  16)
>
> @@ -996,15 +996,13 @@ static int m25p_probe(struct spi_device *spi)
>   		}
>   	}
>
> -	flash = kzalloc(sizeof *flash, GFP_KERNEL);
> +	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
>   	if (!flash)
>   		return -ENOMEM;
> -	flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
> -					GFP_KERNEL);
> -	if (!flash->command) {
> -		kfree(flash);
> +
> +	flash->command = devm_kzalloc(&spi->dev, MAX_CMD_SIZE, GFP_KERNEL);
> +	if (!flash->command)
>   		return -ENOMEM;
> -	}
>
>   	flash->spi = spi;
>   	mutex_init(&flash->lock);
> @@ -1137,14 +1135,10 @@ static int m25p_probe(struct spi_device *spi)
>   static int m25p_remove(struct spi_device *spi)
>   {
>   	struct m25p	*flash = spi_get_drvdata(spi);
> -	int		status;
>
>   	/* Clean up MTD stuff. */
> -	status = mtd_device_unregister(&flash->mtd);
> -	if (status == 0) {
> -		kfree(flash->command);
> -		kfree(flash);
> -	}
> +	mtd_device_unregister(&flash->mtd);
> +
>   	return 0;
>   }
>



From sourav.poddar at ti.com  Thu Oct 24 05:01:07 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:31:07 +0530
Subject: [PATCH 2/5] mtd: m25p80: remove obsolete FIXME
In-Reply-To: <1382583503-13748-2-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-2-git-send-email-computersforpeace@gmail.com>
Message-ID: <5268E1D3.2040304@ti.com>

On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
> The FIXME and NOTE have already been fixed (we have FAST_READ support).
>
> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
Reviewed-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
>   drivers/mtd/devices/m25p80.c | 9 ---------
>   1 file changed, 9 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 63a95ac..7c4cbad 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -367,10 +367,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
>   	spi_message_init(&m);
>   	memset(t, 0, (sizeof t));
>
> -	/* NOTE:
> -	 * OPCODE_FAST_READ (if available) is faster.
> -	 * Should add 1 byte DUMMY_BYTE.
> -	 */
>   	t[0].tx_buf = flash->command;
>   	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
>   	spi_message_add_tail(&t[0],&m);
> @@ -388,11 +384,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
>   		return 1;
>   	}
>
> -	/* FIXME switch to OPCODE_FAST_READ.  It's required for higher
> -	 * clocks; and at this writing, every chip this driver handles
> -	 * supports that opcode.
> -	 */
> -
>   	/* Set up the write data buffer. */
>   	opcode = flash->read_opcode;
>   	flash->command[0] = opcode;



From sourav.poddar at ti.com  Thu Oct 24 05:01:28 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:31:28 +0530
Subject: [PATCH 3/5] mtd: m25p80: re-align ID entries
In-Reply-To: <1382583503-13748-3-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-3-git-send-email-computersforpeace@gmail.com>
Message-ID: <5268E1E8.5020909@ti.com>

On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
> No change in the table data.
>
> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
Reviewed-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
>   drivers/mtd/devices/m25p80.c | 32 ++++++++++++++++----------------
>   1 file changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 7c4cbad..7e3ec7a 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -740,19 +740,19 @@ static const struct spi_device_id m25p_ids[] = {
>   	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
>
>   	/* EON -- en25xxx */
> -	{ "en25f32", INFO(0x1c3116, 0, 64 * 1024,  64, SECT_4K) },
> -	{ "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
> -	{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024,  64, 0) },
> -	{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
> -	{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
> -	{ "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
> +	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
> +	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
> +	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
> +	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
> +	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
> +	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
>
>   	/* ESMT */
>   	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) },
>
>   	/* Everspin */
> -	{ "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) },
> -	{ "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) },
> +	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) },
> +	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) },
>
>   	/* GigaDevice */
>   	{ "gd25q32", INFO(0xc84016, 0, 64 * 1024,  64, SECT_4K) },
> @@ -777,16 +777,16 @@ static const struct spi_device_id m25p_ids[] = {
>   	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
>
>   	/* Micron */
> -	{ "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
> -	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024, 256, 0) },
> -	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
> -	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
> -	{ "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
> +	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
> +	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, 0) },
> +	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, 0) },
> +	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K) },
> +	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) },
>
>   	/* PMC */
> -	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
> -	{ "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
> -	{ "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
> +	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
> +	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
>
>   	/* Spansion -- single (large) sector size only, at least
>   	 * for the chips listed here (without boot sectors).



From sourav.poddar at ti.com  Thu Oct 24 05:01:58 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:31:58 +0530
Subject: [PATCH 5/5] mtd: m25p80: remove 'disabled' device check
In-Reply-To: <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>
Message-ID: <5268E206.5080602@ti.com>

On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
> It seems like the following commit was never necessary
>
>      commit 5f949137952020214cd167093dd7be448f21c079
>      Author: Shaohui Xie<Shaohui.Xie at freescale.com>
>      Date:   Fri Oct 14 15:49:00 2011 +0800
>
>          mtd: m25p80: don't probe device which has status of 'disabled'
>
> because it duplicates the code in of_platform_device_create_pdata()
> which ensures that 'disabled' nodes are never instantiated.
>
> Also, drop the __maybe_unused.
>
> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
> Cc: Grant Likely<grant.likely at linaro.org>
> Cc: Rob Herring<rob.herring at calxeda.com>
> Cc:<devicetree at vger.kernel.org>
Reviewed-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
>   drivers/mtd/devices/m25p80.c | 7 +------
>   1 file changed, 1 insertion(+), 6 deletions(-)
>
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index d6c5c57..a1dc49a 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -935,12 +935,7 @@ static int m25p_probe(struct spi_device *spi)
>   	struct flash_info		*info;
>   	unsigned			i;
>   	struct mtd_part_parser_data	ppdata;
> -	struct device_node __maybe_unused *np = spi->dev.of_node;
> -
> -#ifdef CONFIG_MTD_OF_PARTS
> -	if (!of_device_is_available(np))
> -		return -ENODEV;
> -#endif
> +	struct device_node *np = spi->dev.of_node;
>
>   	/* Platform data helps sort out which chip type we have, as
>   	 * well as how this board partitions it.  If we don't have



From b32955 at freescale.com  Thu Oct 24 04:48:16 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 24 Oct 2013 16:48:16 +0800
Subject: [PATCH v2 fix] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382602484-12023-1-git-send-email-b32955@freescale.com>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
Message-ID: <1382604496-28118-1-git-send-email-b32955@freescale.com>

The legacy ecc layout is to use all the OOB area by computing the ecc strength
and ecc step size ourselves.

The patch "2febcdf mtd: gpmi: set the BCHs geometry with the ecc info"
makes the gpmi to use the ECC info(ecc strength and ecc step size)
provided by the MTD code, and creates a different NAND ecc layout
for the BCH , and use the new ecc layout, this brings a regression to us:
   We can not mount the ubifs which was created by the old NAND ecc layout.

This patch fixes this issue by use the legacy ecc layout firstly, if it fails
we try to use the new ecc layout.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
Cc: stable at vger.kernel.org
---
 revert the return value of set_geometry_by_ecc_info().

---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 6807d7c..43a62e8 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -352,7 +352,8 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
-	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
+	return legacy_set_geometry(this) ?
+		(!set_geometry_by_ecc_info(this)) : 0;
 }
 
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
-- 
1.7.2.rc3




From sourav.poddar at ti.com  Thu Oct 24 05:07:40 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:37:40 +0530
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
Message-ID: <5268E35C.2030000@ti.com>

Hi Brian,
On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
> Remove the compile-time option for FAST_READ, since we have run-time
> support for detecting it.
>
> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
> ---
>   drivers/mtd/devices/Kconfig  |  7 -------
>   drivers/mtd/devices/m25p80.c | 11 ++++++-----
>   2 files changed, 6 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> index 74ab4b7..0128138 100644
> --- a/drivers/mtd/devices/Kconfig
> +++ b/drivers/mtd/devices/Kconfig
> @@ -95,13 +95,6 @@ config MTD_M25P80
>   	  if you want to specify device partitioning or to use a device which
>   	  doesn't support the JEDEC ID instruction.
>
> -config M25PXX_USE_FAST_READ
> -	bool "Use FAST_READ OPCode allowing SPI CLK>= 50MHz"
> -	depends on MTD_M25P80
> -	default y
> -	help
> -	  This option enables FAST_READ access supported by ST M25Pxx.
> -
>   config MTD_SPEAR_SMI
>   	tristate "SPEAR MTD NOR Support through SMI controller"
>   	depends on PLAT_SPEAR
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 7e3ec7a..d6c5c57 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
>   	flash->page_size = info->page_size;
>   	flash->mtd.writebufsize = flash->page_size;
>
> -	flash->fast_read = false;
> -	if (np&&  of_property_read_bool(np, "m25p,fast-read"))
> +	if (np)
> +		/* If we were instantiated by DT, use it */
> +		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
> +	else
> +		/* If we weren't instantiated by DT, default to fast-read */
>   		flash->fast_read = true;
>
This comment is in sync with my quad read mode support patch on the mtd 
list.

Here, you are defaulting the fast read to be true. Once I add quad mode
on top of this, I will set flash->quad_read = true. So, we will have both
fast and quad read set(which will not be correct). So, it is necessary 
to default to fast read ?
> -#ifdef CONFIG_M25PXX_USE_FAST_READ
> -	flash->fast_read = true;
> -#endif
> +	/* Some devices cannot do fast-read, no matter what DT tells us */
>   	if (info->flags&  M25P_NO_FR)
>   		flash->fast_read = false;
>



From sourav.poddar at ti.com  Thu Oct 24 05:12:53 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 14:42:53 +0530
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <5268E35C.2030000@ti.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
 <5268E35C.2030000@ti.com>
Message-ID: <5268E495.5010707@ti.com>

On Thursday 24 October 2013 02:37 PM, Sourav Poddar wrote:
> Hi Brian,
> On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
>> Remove the compile-time option for FAST_READ, since we have run-time
>> support for detecting it.
>>
>> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
>> ---
>>   drivers/mtd/devices/Kconfig  |  7 -------
>>   drivers/mtd/devices/m25p80.c | 11 ++++++-----
>>   2 files changed, 6 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
>> index 74ab4b7..0128138 100644
>> --- a/drivers/mtd/devices/Kconfig
>> +++ b/drivers/mtd/devices/Kconfig
>> @@ -95,13 +95,6 @@ config MTD_M25P80
>>         if you want to specify device partitioning or to use a device 
>> which
>>         doesn't support the JEDEC ID instruction.
>>
>> -config M25PXX_USE_FAST_READ
>> -    bool "Use FAST_READ OPCode allowing SPI CLK>= 50MHz"
>> -    depends on MTD_M25P80
>> -    default y
>> -    help
>> -      This option enables FAST_READ access supported by ST M25Pxx.
>> -
>>   config MTD_SPEAR_SMI
>>       tristate "SPEAR MTD NOR Support through SMI controller"
>>       depends on PLAT_SPEAR
>> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
>> index 7e3ec7a..d6c5c57 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
>> @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
>>       flash->page_size = info->page_size;
>>       flash->mtd.writebufsize = flash->page_size;
>>
>> -    flash->fast_read = false;
>> -    if (np&&  of_property_read_bool(np, "m25p,fast-read"))
>> +    if (np)
>> +        /* If we were instantiated by DT, use it */
>> +        flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
>> +    else
>> +        /* If we weren't instantiated by DT, default to fast-read */
>>           flash->fast_read = true;
>>
> This comment is in sync with my quad read mode support patch on the 
> mtd list.
>
> Here, you are defaulting the fast read to be true. Once I add quad mode
> on top of this, I will set flash->quad_read = true. So, we will have both
> fast and quad read set(which will not be correct). So, it is necessary 
> to default to fast read ?
Though, we will hit this scenario only for a non dt case. For dt case, 
things will be fine.
>> -#ifdef CONFIG_M25PXX_USE_FAST_READ
>> -    flash->fast_read = true;
>> -#endif
>> +    /* Some devices cannot do fast-read, no matter what DT tells us */
>>       if (info->flags&  M25P_NO_FR)
>>           flash->fast_read = false;
>>
>



From prabhakar at freescale.com  Thu Oct 24 05:56:43 2013
From: prabhakar at freescale.com (Prabhakar Kushwaha)
Date: Thu, 24 Oct 2013 15:26:43 +0530
Subject: [PATCH] driver/mtd/IFC: Add support of 8K page size NAND flash
In-Reply-To: <20131023164332.GU23337@ld-irv-0074.broadcom.com>
References: <1380021083-15986-1-git-send-email-prabhakar@freescale.com>
 <20131023164332.GU23337@ld-irv-0074.broadcom.com>
Message-ID: <5268EEDB.8000406@freescale.com>

On 10/23/2013 10:13 PM, Brian Norris wrote:
> On Tue, Sep 24, 2013 at 04:41:23PM +0530, Prabhakar Kushwaha wrote:
>> Current IFC driver supports till 4K page size NAND flash.
>> Add support of 8K Page size NAND flash
>>    - Add nand_ecclayout for 4 bit & 8 bit ecc
>>    - Defines constants
>>    - also fix ecc.strength for 8bit ecc of 8K page size NAND
>>
>> Signed-off-by: Prabhakar Kushwaha <prabhakar at freescale.com>
> These ECC layouts are rather horrendous and large, but they're the best
> we've got...
>
> Pushed to l2-mtd.git with compile testing only. Let me know if there are
> any Tested-by's (or NAK's).
>
>
Thanks Brian for applying this patch to l2-mtd.git.
I only tested this patch.

This same patch has been pushed for review on u-boot mailing list. Till 
now no comments.
means no NAK's :)

Regards,
Prabhakar






From b32955 at freescale.com  Thu Oct 24 06:59:51 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Thu, 24 Oct 2013 18:59:51 +0800
Subject: [PATCH v2] flash_erase: check the nand type
Message-ID: <1382612391-13036-1-git-send-email-b32955@freescale.com>

Now, the MTD_NANDFLASH stands for SLC nand, and the MTD_MLCNANDFLASH
stands for the MLC nand.

This patch includes the stdbool.h, and changes the "isNAND" to boolean type,
and checks the right nand type for the MLC and SLC nand.

If the user wants to format a MLC nand for JFFS2, we will print out a message
to warn him, and exit right now.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 flash_erase.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/flash_erase.c b/flash_erase.c
index 1421cf9..933373a 100644
--- a/flash_erase.c
+++ b/flash_erase.c
@@ -21,6 +21,7 @@
 #define PROGRAM_NAME "flash_erase"
 
 #include <inttypes.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -95,7 +96,7 @@ int main(int argc, char *argv[])
 	int fd, clmpos = 0, clmlen = 8;
 	unsigned long long start;
 	unsigned int eb, eb_start, eb_cnt;
-	int isNAND;
+	bool isNAND;
 	int error = 0;
 	off_t offset = 0;
 
@@ -182,9 +183,12 @@ int main(int argc, char *argv[])
 	if (mtd_get_dev_info(mtd_desc, mtd_device, &mtd) < 0)
 		return errmsg("mtd_get_dev_info failed");
 
+	if (jffs2 && mtd.type == MTD_MLCNANDFLASH)
+		return errmsg("JFFS2 cannot support MLC NAND.");
+
 	eb_start = start / mtd.eb_size;
 
-	isNAND = mtd.type == MTD_NANDFLASH ? 1 : 0;
+	isNAND = mtd.type == MTD_NANDFLASH || mtd.type == MTD_MLCNANDFLASH;
 
 	if (jffs2) {
 		cleanmarker.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
-- 
1.7.2.rc3




From bindari at dienteslindos.cl  Thu Oct 24 07:36:31 2013
From: bindari at dienteslindos.cl (=?iso-8859-5?B?tdvV3dAgtNzY4uDY1dLd0A==?=)
Date: Thu, 24 Oct 2013 13:36:31 +0200
Subject: =?iso-8859-5?B?susg4dze1tXi1SDS29DU1eLsINfQ0tjU3evcINfg?=
 =?iso-8859-5?B?1d3Y1dw=?=
Message-ID: <B86CF2EE0D4B4CF5AE69337CFD6E6E99@odmxcwv>

?????? ????- ????????? ?????? http://etnatour.com.ua/bitrix/backup/cghwm.htm


From pekon at ti.com  Thu Oct 24 08:50:17 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:17 +0530
Subject: [PATCH v11 01/10] ARM: OMAP2+: cleaned-up DT support of various ECC
 schemes
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-2-git-send-email-pekon@ti.com>

OMAP NAND driver support multiple ECC scheme, which can used in different
flavours, depending on in-build Hardware engines present on SoC.

This patch updates following in DT bindings related to sectionion of ecc-schemes
- ti,elm-id: replaces elm_id (maintains backward compatibility)
- ti,nand-ecc-opts: selection of h/w or s/w implementation of an ecc-scheme
	depends on ti,elm-id. (supported values ham1, bch4, and bch8)
- maintain backward compatibility to deprecated DT bindings (sw, hw, hw-romcode)

Below table shows different flavours of ecc-schemes supported by OMAP devices
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W            |
|(requires CONFIG_MTD_NAND_ECC_BCH)     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
|(requires CONFIG_MTD_NAND_OMAP_BCH &&  |               |               |
| ti,elm-id in DT)                      |               |               |
+---------------------------------------+---------------+---------------+

To optimize footprint of omap2-nand driver, selection of some ECC schemes
also require enabling following Kconfigs, in addition to setting appropriate
DT bindings
- Kconfig:CONFIG_MTD_NAND_ECC_BCH        error detection done in software
- Kconfig:CONFIG_MTD_NAND_OMAP_BCH       error detection done by h/w engine

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  8 +++-
 arch/arm/mach-omap2/gpmc.c                         | 48 +++++++++++++++-------
 include/linux/platform_data/mtd-nand-omap2.h       | 13 +++++-
 3 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index df338cb..bfe07e1 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -36,8 +36,12 @@ Optional properties:
 		"prefetch-dma"		Prefetch enabled sDMA mode
 		"prefetch-irq"		Prefetch enabled irq mode
 
- - elm_id:	Specifies elm device node. This is required to support BCH
- 		error correction using ELM module.
+ - elm_id:	<deprecated> use "ti,elm-id" instead
+ - ti,elm-id:	Specifies phandle of the ELM devicetree node.
+		ELM is an on-chip hardware engine on TI SoC which is used for
+		locating ECC errors for BCHx algorithms. SoC devices which have
+		ELM hardware engines should specify this device node in .dtsi
+		Using ELM for ECC error correction frees some CPU cycles.
 
 For inline partiton table parsing (optional):
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 579697a..c877129 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1341,14 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 
 #ifdef CONFIG_MTD_NAND
 
-static const char * const nand_ecc_opts[] = {
-	[OMAP_ECC_HAMMING_CODE_DEFAULT]		= "sw",
-	[OMAP_ECC_HAMMING_CODE_HW]		= "hw",
-	[OMAP_ECC_HAMMING_CODE_HW_ROMCODE]	= "hw-romcode",
-	[OMAP_ECC_BCH4_CODE_HW]			= "bch4",
-	[OMAP_ECC_BCH8_CODE_HW]			= "bch8",
-};
-
 static const char * const nand_xfer_types[] = {
 	[NAND_OMAP_PREFETCH_POLLED]		= "prefetch-polled",
 	[NAND_OMAP_POLLED]			= "polled",
@@ -1378,13 +1370,41 @@ static int gpmc_probe_nand_child(struct platform_device *pdev,
 	gpmc_nand_data->cs = val;
 	gpmc_nand_data->of_node = child;
 
-	if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
-		for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
-			if (!strcasecmp(s, nand_ecc_opts[val])) {
-				gpmc_nand_data->ecc_opt = val;
-				break;
-			}
+	/* Detect availability of ELM module */
+	gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		gpmc_nand_data->elm_of_node =
+					of_parse_phandle(child, "elm_id", 0);
+	if (gpmc_nand_data->elm_of_node == NULL)
+		pr_warn("%s: ti,elm-id property not found\n", __func__);
+
+	/* select ecc-scheme for NAND */
+	if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) {
+		pr_err("%s: ti,nand-ecc-opt not found\n", __func__);
+		return -ENODEV;
+	}
+	if (!strcmp(s, "ham1") || !strcmp(s, "sw") ||
+		!strcmp(s, "hw") || !strcmp(s, "hw-romcode"))
+		gpmc_nand_data->ecc_opt =
+				OMAP_ECC_HAM1_CODE_HW;
+	else if (!strcmp(s, "bch4"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
+	else if (!strcmp(s, "bch8"))
+		if (gpmc_nand_data->elm_of_node)
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW;
+		else
+			gpmc_nand_data->ecc_opt =
+				OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
+	else
+		pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__);
 
+	/* select data transfer mode for NAND controller */
 	if (!of_property_read_string(child, "ti,nand-xfer-type", &s))
 		for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++)
 			if (!strcasecmp(s, nand_xfer_types[val])) {
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 6bf9ef4..e4128f1 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -28,8 +28,16 @@ enum omap_ecc {
 	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 */
+	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_HAM1_CODE_HW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
+	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH4_CODE_HW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by Software */
+	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
+	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */
+	OMAP_ECC_BCH8_CODE_HW,
 };
 
 struct gpmc_nand_regs {
@@ -63,5 +71,6 @@ struct omap_nand_platform_data {
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
+	struct device_node	*elm_of_node;
 };
 #endif
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:16 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:16 +0530
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up of
 supported ECC schemes
Message-ID: <1382619026-4182-1-git-send-email-pekon@ti.com>

*changes v10 -> v11*
- [PATCH v10 04/10] replaced with newer [PATCH v11 04/11] so that
  nand_scan_ident() is called only once.
  discussion thread with Brian Norris <computersforpeace at gmail.com>
  <http://lists.infradead.org/pipermail/linux-mtd/2013-October/049335.html>
- No change in any other patch


*changes v9 -> v10*
[PATCH 1/10], [PATCH 2/10]
  swapped [PATCH v9 1/9] and [PATCH v9 2/9] so that DT parsing updates
  (with backward compatibility) happen before the deprecation of DT values.
  This way DTB does not break functionally between the patches.
[PATCH 3/10] <no update>
[PATCH 4/10] 
  dropped [PATCH v9 4/9] introducing NAND_BUSWIDTH_AUTO, instead
  using DT 'nand-bus-width' for device bus-width. Refer discussion thread 
  <http://lists.infradead.org/pipermail/linux-mtd/2013-October/049198.html>
[PATCH 5/10] <no update>
[PATCH 6/10] <no update>
[PATCH 7/10] 
  separated out drivers/mtd/nand/Kconfig updates into separate [PATCH v10 10/10]
  cleanup: s/info->nand\./nand_chip->
[PATCH 8/10] <no update>
[PATCH 9/10] cleanup: s/out_release_mem_region/return_error
[PATCH 10/10] <new> spawned from [PATCH v9 8/9] for Kconfig updates


*changes v8 -> v9*
[PATCH 1/9] <no update from [PATCH v8 1/6]>
[PATCH 2/9] <only commit log updated from [PATCH v8 2/6]>
 As per feedbacks from Brian Norris <computersforpeace at gmail.com> previous
 revision [PATCH v8 3/6] and [PATCH 4/6] are split into following sub-patches:
- [PATCH 3/9] <new> replaces local reference with generic names (mtd, nand_chip)
- [PATCH 4/9] <new> enables auto-detection of bus-width
- [PATCH 5/9] <new> removes omap3_init_bch: populates ecc-scheme data
- [PATCH 6/9] <new> removes omap3_init_bch_tail: populates ecc-layout
- [PATCH 7/9] <new> replaces lib/bch.c with nand_bch.c wrapper
[PATCH 8/9] <no update same as [PATCH v8 5/6]
[PATCH 9/9] removed devm_free_xx functions


*Changes v7 -> v8*
[PATCH 1/6] <no updates>
[PATCH 2/6]
	- updated DT parsing of "ti,nand-ecc-opts" so that its "ham1" remains
		compatible to "sw","hw","hw-romcode"
	- updated DT parsing of "ti,elm-id" to retain compatibility to "elm_id"
	- using of_parse_phandle() to get ELM device pointer from DT
[PATCH 3..6/6] <commit log updates>


*Changes v6 -> v7*
[PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks from Brian Norris <computersforpeace at gmail.com>
[PATCH 2/6] incorporated feedbacks from DT maintainers
[PATCH 3/6] cleaned and incorporated feedbacks from Brian Norris <computersforpeace at gmail.com>
[PATCH 4/6] rebasing changes and cleanup
[PATCH 5/6] updated omap3430-sdp.dts
[PATCH 6/6] <NEW> updated for devm_xx


*Changes v5 -> v6*
[PATCH 1/4]: 
	- updated DT binding for gpmc-nand based on 'Olof Johansson's feedbacks
	http://lists.infradead.org/pipermail/linux-mtd/2013-August/048394.html
	- detection of ELM device via ti,elm-id DT node, moved to gpmc.c driver
[PATCH 2/4]
	- removed: support for following obselete ECC schemes
	OMAP_ECC_HAMMING_CODE_DEFAULT (S/W based 1-bit Hamming ECC)
	OMAP_ECC_HAMMING_CODE_HW_ROMCODE (H/W based 1-bit Hamming ECC scheme)
	- updated: using omap_oobinfo as chip->ecc.layout for all ecc-schemes
	- clean: error messages
[PATCH 3/4] cleaned to include changes for OMAP_ECC_BCH8_CODE_HW only
[PATCH 4/4] updated to include DT property changes


*Changes v4 -> v5*
- Rebased to linux-next 
IMPORTANT: Need to revert commit fb1585b, [PATCH 2/4] part of previous version
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047441.html

- Swapped PATCH-1 & PATCH-2 to maintain bisectibility & compilation dependency
	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047461.html

- PATCH-2: re-ordered call to is_elm_present() for later updates ELM driver
	- dropped changes in include/linux/platform_data/elm.h (not needed)
- PATCH-3: re-ordered call to is_elm_present() for later updates ELM driver
- Re-formated patch description (replaced tabs with white-spaces)


*Changes v3 -> v4*
(Resent with CC: devicetree-discuss at lists.ozlabs.org)
- [Patch 1/3] removed MTD_NAND_OMAP_BCH8 & MTD_NAND_OMAP_BCH4 from nand/Kconfig
	ECC scheme selectable via nand DT (nand-ecc-opt).
- [*] rebased for l2-mtd.git


*Changes v2 -> v3*
(Resent with Author Name fixed)
- PATCH-1: re-arranged code to remove redundancy, added NAND_BUSWIDTH_AUTO
- PATCH-2: updated nand-ecc-opt DT mapping and Documentation
- PATCH-3: code-cleaning + changes to match PATCH-1
- PATCH-4 <DROPPED> update DT attribute for ti,nand-ecc-opt 
	- received feedback to keep DT mapping independent of linuxism
- PATCH-4:<NEW> : ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
	- independent patch for AM335x-evm.dts update based on PATCH-2


*Changes v1 -> v2*
	added 	[PATCH 3/4] and [PATCH 4/4]


After this patch series, omap2-nand driver will supports following ECC schemes:
+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+


Pekon Gupta (10):
  ARM: OMAP2+: cleaned-up DT support of various ECC schemes
  mtd: nand: omap: combine different flavours of 1-bit hamming ecc
    schemes
  mtd: nand: omap: cleanup: replace local references with generic
    framework names
  mtd: nand: omap: use DT specified bus-width only for scanning NAND
    device
  mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
    device_probe
  mtd: nand: omap: clean-up ecc layout for BCH ecc schemes
  mtd: nand: omap: use drivers/mtd/nand/nand_bch.c wrapper for BCH ECC
    instead of lib/bch.c
  ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
  mtd: nand: omap: updated devm_xx for all resource allocation and free
    calls
  mtd: nand: omap: remove selection of BCH ecc-scheme via KConfig

 .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
 arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
 arch/arm/mach-omap2/board-flash.c                  |   2 +-
 arch/arm/mach-omap2/gpmc.c                         |  48 +-
 drivers/mtd/nand/Kconfig                           |  40 +-
 drivers/mtd/nand/omap2.c                           | 641 +++++++++------------
 include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
 8 files changed, 348 insertions(+), 422 deletions(-)

-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:18 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:18 +0530
Subject: [PATCH v11 02/10] mtd: nand: omap: combine different flavours of
 1-bit hamming ecc schemes
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-3-git-send-email-pekon@ti.com>

OMAP NAND driver currently supports multiple flavours of 1-bit Hamming
ecc-scheme, like:
- OMAP_ECC_HAMMING_CODE_DEFAULT
	1-bit hamming ecc code using software library
- OMAP_ECC_HAMMING_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine
- OMAP_ECC_HAMMING_CODE_HW_ROMCODE
	1-bit hamming ecc-code using GPMC h/w engin with ecc-layout compatible
	to ROM code.

This patch combines above multiple ecc-schemes into single implementation:
- OMAP_ECC_HAM1_CODE_HW
	1-bit hamming ecc-code using GPMC h/w engine with ROM-code compatible
	ecc-layout.

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
Acked-by: Tony Lindgren <tony at atomide.com>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 8 ++++----
 arch/arm/mach-omap2/board-flash.c                   | 2 +-
 drivers/mtd/nand/omap2.c                            | 9 +++------
 include/linux/platform_data/mtd-nand-omap2.h        | 7 +------
 4 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index bfe07e1..5e1f31b 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -22,10 +22,10 @@ Optional properties:
 				width of 8 is assumed.
 
  - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-
-		"sw"		Software method (default)
-		"hw"		Hardware method
-		"hw-romcode"	gpmc hamming mode method & romcode layout
+		"sw"		<deprecated> use "ham1" instead
+		"hw"		<deprecated> use "ham1" instead
+		"hw-romcode"	<deprecated> use "ham1" instead
+		"ham1"		1-bit Hamming ecc code
 		"bch4"		4-bit BCH ecc code
 		"bch8"		8-bit BCH ecc code
 
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index fc20a61..ac82512 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs,
 	board_nand_data.nr_parts	= nr_parts;
 	board_nand_data.devsize		= nand_type;
 
-	board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT;
+	board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW;
 	gpmc_nand_init(&board_nand_data, gpmc_t);
 }
 #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..8d521aa 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1993,10 +1993,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
-		info->nand.ecc.mode = NAND_ECC_SOFT;
-	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
-		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 		info->nand.ecc.bytes            = 3;
 		info->nand.ecc.size             = 512;
 		info->nand.ecc.strength         = 1;
@@ -2025,7 +2022,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
+	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
 		if (info->nand.options & NAND_BUSWIDTH_16)
 			offset = 2;
@@ -2033,7 +2030,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			offset = 1;
 			info->nand.badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.oobsize/16);
+		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index e4128f1..4da5bfa 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -23,13 +23,8 @@ enum nand_io {
 };
 
 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 */
 	/* 1-bit  ECC calculation by GPMC, Error detection by Software */
-	OMAP_ECC_HAM1_CODE_HW,
+	OMAP_ECC_HAM1_CODE_HW = 0,
 	/* 4-bit  ECC calculation by GPMC, Error detection by Software */
 	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW,
 	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:20 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:20 +0530
Subject: [PATCH v11 04/10] mtd: nand: omap: use DT specified bus-width only
 for scanning NAND device
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-5-git-send-email-pekon@ti.com>

This patch:
- calls nand_scan_ident() using bus-width as passed by DT
- removes double calls to nand_scan_ident(), incase first call fails
  then omap_nand_probe just returns error.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 5596368..f464321 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
-	nand_chip->options	= pdata->devsize;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
@@ -1904,6 +1903,15 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->chip_delay = 50;
 	}
 
+	/* scan NAND device connected to chip controller */
+	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		pr_err("nand device scan failed, may be bus-width mismatch\n");
+		err = -ENXIO;
+		goto out_release_mem_region;
+	}
+
+	/* re-populate low-level callbacks based on xfer modes */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		nand_chip->read_buf   = omap_read_buf_pref;
@@ -2011,17 +2019,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(mtd, 1, NULL)) {
-		nand_chip->options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(mtd, 1, NULL)) {
-			err = -ENXIO;
-			goto out_release_mem_region;
-		}
-	}
-
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:19 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:19 +0530
Subject: [PATCH v11 03/10] mtd: nand: omap: cleanup: replace local references
 with generic framework names
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-4-git-send-email-pekon@ti.com>

This patch updates following in omap_nand_probe() and omap_nand_remove()
- replaces "info->nand" with "nand_chip" (struct nand_chip *nand_chip)
- replaces "info->mtd" with "mtd" (struct mtd_info *mtd)
- white-space and formatting cleanup

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 112 ++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 55 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 8d521aa..5596368 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1824,10 +1824,12 @@ static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
 	struct omap_nand_platform_data	*pdata;
+	struct mtd_info			*mtd;
+	struct nand_chip		*nand_chip;
 	int				err;
 	int				i, offset;
-	dma_cap_mask_t mask;
-	unsigned sig;
+	dma_cap_mask_t			mask;
+	unsigned			sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
 
@@ -1846,17 +1848,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	spin_lock_init(&info->controller.lock);
 	init_waitqueue_head(&info->controller.wq);
 
-	info->pdev = pdev;
-
+	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-
-	info->mtd.priv		= &info->nand;
-	info->mtd.name		= dev_name(&pdev->dev);
-	info->mtd.owner		= THIS_MODULE;
-
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
+	mtd			= &info->mtd;
+	mtd->priv		= &info->nand;
+	mtd->name		= dev_name(&pdev->dev);
+	mtd->owner		= THIS_MODULE;
+	nand_chip		= &info->nand;
+	nand_chip->options	= pdata->devsize;
+	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
 #endif
@@ -1877,16 +1878,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_free_info;
 	}
 
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
-	if (!info->nand.IO_ADDR_R) {
+	nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	if (!nand_chip->IO_ADDR_R) {
 		err = -ENOMEM;
 		goto out_release_mem_region;
 	}
 
-	info->nand.controller = &info->controller;
+	nand_chip->controller = &info->controller;
 
-	info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
-	info->nand.cmd_ctrl  = omap_hwcontrol;
+	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
+	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
@@ -1896,26 +1897,26 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * device and read status register until you get a failure or success
 	 */
 	if (pdata->dev_ready) {
-		info->nand.dev_ready = omap_dev_ready;
-		info->nand.chip_delay = 0;
+		nand_chip->dev_ready = omap_dev_ready;
+		nand_chip->chip_delay = 0;
 	} else {
-		info->nand.waitfunc = omap_wait;
-		info->nand.chip_delay = 50;
+		nand_chip->waitfunc = omap_wait;
+		nand_chip->chip_delay = 50;
 	}
 
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
-		info->nand.read_buf   = omap_read_buf_pref;
-		info->nand.write_buf  = omap_write_buf_pref;
+		nand_chip->read_buf   = omap_read_buf_pref;
+		nand_chip->write_buf  = omap_write_buf_pref;
 		break;
 
 	case NAND_OMAP_POLLED:
-		if (info->nand.options & NAND_BUSWIDTH_16) {
-			info->nand.read_buf   = omap_read_buf16;
-			info->nand.write_buf  = omap_write_buf16;
+		if (nand_chip->options & NAND_BUSWIDTH_16) {
+			nand_chip->read_buf   = omap_read_buf16;
+			nand_chip->write_buf  = omap_write_buf16;
 		} else {
-			info->nand.read_buf   = omap_read_buf8;
-			info->nand.write_buf  = omap_write_buf8;
+			nand_chip->read_buf   = omap_read_buf8;
+			nand_chip->write_buf  = omap_write_buf8;
 		}
 		break;
 
@@ -1944,8 +1945,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 					err);
 				goto out_release_mem_region;
 			}
-			info->nand.read_buf   = omap_read_buf_dma_pref;
-			info->nand.write_buf  = omap_write_buf_dma_pref;
+			nand_chip->read_buf   = omap_read_buf_dma_pref;
+			nand_chip->write_buf  = omap_write_buf_dma_pref;
 		}
 		break;
 
@@ -1980,8 +1981,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 			goto out_release_mem_region;
 		}
 
-		info->nand.read_buf  = omap_read_buf_irq_pref;
-		info->nand.write_buf = omap_write_buf_irq_pref;
+		nand_chip->read_buf  = omap_read_buf_irq_pref;
+		nand_chip->write_buf = omap_write_buf_irq_pref;
 
 		break;
 
@@ -1994,16 +1995,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	/* select the ecc type */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-		info->nand.ecc.bytes            = 3;
-		info->nand.ecc.size             = 512;
-		info->nand.ecc.strength         = 1;
-		info->nand.ecc.calculate        = omap_calculate_ecc;
-		info->nand.ecc.hwctl            = omap_enable_hwecc;
-		info->nand.ecc.correct          = omap_correct_data;
-		info->nand.ecc.mode             = NAND_ECC_HW;
+		nand_chip->ecc.bytes            = 3;
+		nand_chip->ecc.size             = 512;
+		nand_chip->ecc.strength         = 1;
+		nand_chip->ecc.calculate        = omap_calculate_ecc;
+		nand_chip->ecc.hwctl            = omap_enable_hwecc;
+		nand_chip->ecc.correct          = omap_correct_data;
+		nand_chip->ecc.mode             = NAND_ECC_HW;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(&info->mtd, pdata->ecc_opt);
+		err = omap3_init_bch(mtd, pdata->ecc_opt);
 		if (err) {
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2013,9 +2014,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 	/* DIP switches on some boards change between 8 and 16 bit
 	 * bus widths for flash.  Try the other width if the first try fails.
 	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		nand_chip->options ^= NAND_BUSWIDTH_16;
+		if (nand_scan_ident(mtd, 1, NULL)) {
 			err = -ENXIO;
 			goto out_release_mem_region;
 		}
@@ -2024,25 +2025,25 @@ static int omap_nand_probe(struct platform_device *pdev)
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
 
-		if (info->nand.options & NAND_BUSWIDTH_16)
+		if (nand_chip->options & NAND_BUSWIDTH_16) {
 			offset = 2;
-		else {
+		} else {
 			offset = 1;
-			info->nand.badblock_pattern = &bb_descrip_flashbased;
+			nand_chip->badblock_pattern = &bb_descrip_flashbased;
 		}
-		omap_oobinfo.eccbytes = 3 * (info->mtd.writesize / 512);
+		omap_oobinfo.eccbytes = 3 * (mtd->writesize / 512);
 		for (i = 0; i < omap_oobinfo.eccbytes; i++)
 			omap_oobinfo.eccpos[i] = i+offset;
 
 		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = info->mtd.oobsize -
+		omap_oobinfo.oobfree->length = mtd->oobsize -
 					(offset + omap_oobinfo.eccbytes);
 
-		info->nand.ecc.layout = &omap_oobinfo;
+		nand_chip->ecc.layout = &omap_oobinfo;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
 		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(&info->mtd);
+		err = omap3_init_bch_tail(mtd);
 		if (err) {
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2050,16 +2051,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* second phase scan */
-	if (nand_scan_tail(&info->mtd)) {
+	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
 		goto out_release_mem_region;
 	}
 
 	ppdata.of_node = pdata->of_node;
-	mtd_device_parse_register(&info->mtd, NULL, &ppdata, pdata->parts,
+	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts,
 				  pdata->nr_parts);
 
-	platform_set_drvdata(pdev, &info->mtd);
+	platform_set_drvdata(pdev, mtd);
 
 	return 0;
 
@@ -2080,9 +2081,10 @@ out_free_info:
 static int omap_nand_remove(struct platform_device *pdev)
 {
 	struct mtd_info *mtd = platform_get_drvdata(pdev);
+	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(&info->mtd);
+	omap3_free_bch(mtd);
 
 	if (info->dma)
 		dma_release_channel(info->dma);
@@ -2093,8 +2095,8 @@ static int omap_nand_remove(struct platform_device *pdev)
 		free_irq(info->gpmc_irq_fifo, info);
 
 	/* Release NAND device, its internal structures and partitions */
-	nand_release(&info->mtd);
-	iounmap(info->nand.IO_ADDR_R);
+	nand_release(mtd);
+	iounmap(nand_chip->IO_ADDR_R);
 	release_mem_region(info->phys_base, info->mem_size);
 	kfree(info);
 	return 0;
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:22 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:22 +0530
Subject: [PATCH v11 06/10] mtd: nand: omap: clean-up ecc layout for BCH ecc
 schemes
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-7-git-send-email-pekon@ti.com>

In current implementation omap3_init_bch_tail() is a common function to
define ecc layout for different BCHx ecc schemes.This patch:
(1) removes omap3_init_bch_tail() and defines ecc layout for individual
    ecc-schemes along with populating their nand_chip->ecc data in
    omap_nand_probe(). This improves the readability and scalability of
    code for add new ecc schemes in future.
(2) removes 'struct nand_bbt_descr bb_descrip_flashbased' because default
    nand_bbt_descr in nand_bbt.c matches the same (.len=1 for x8 devices).
(3) add the check to see if NAND device has enough OOB/Spare bytes to
    store ECC signature of whole page, as defined by ecc-scheme.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 161 ++++++++++++++++++-----------------------------
 1 file changed, 62 insertions(+), 99 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 86ce48b..b6a08b2 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -139,6 +139,7 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define BADBLOCK_MARKER_LENGTH		2
 #define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
@@ -149,17 +150,6 @@ static u_char bch4_vector[] = {0x00, 0x6b, 0x31, 0xdd, 0x41, 0xbc, 0x10};
 
 /* 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
- * while scanning a device for factory marked good / bad blocks
- */
-static uint8_t scan_ff_pattern[] = { 0xff };
-static struct nand_bbt_descr bb_descrip_flashbased = {
-	.options = NAND_BBT_SCANALLPAGES,
-	.offs = 0,
-	.len = 1,
-	.pattern = scan_ff_pattern,
-};
-
 
 struct omap_nand_info {
 	struct nand_hw_control		controller;
@@ -184,7 +174,6 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct bch_control             *bch;
-	struct nand_ecclayout           ecclayout;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1686,65 +1675,8 @@ static void omap3_free_bch(struct mtd_info *mtd)
 	}
 }
 
-/**
- * omap3_init_bch_tail - Build an oob layout for BCH ECC correction.
- * @mtd: MTD device structure
- */
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	int i, steps, offset;
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	struct nand_ecclayout *layout = &info->ecclayout;
-
-	/* build oob layout */
-	steps = mtd->writesize/info->nand.ecc.size;
-	layout->eccbytes = steps*info->nand.ecc.bytes;
-
-	/* do not bother creating special oob layouts for small page devices */
-	if (mtd->oobsize < 64) {
-		pr_err("BCH ecc is not supported on small page devices\n");
-		goto fail;
-	}
-
-	/* reserve 2 bytes for bad block marker */
-	if (layout->eccbytes+2 > mtd->oobsize) {
-		pr_err("no oob layout available for oobsize %d eccbytes %u\n",
-		       mtd->oobsize, layout->eccbytes);
-		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] = 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].length = mtd->oobsize-2-layout->eccbytes;
-	info->nand.ecc.layout = layout;
-
-	if (!(info->nand.options & NAND_BUSWIDTH_16))
-		info->nand.badblock_pattern = &bb_descrip_flashbased;
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
-}
-
 #else
-static int omap3_init_bch_tail(struct mtd_info *mtd)
-{
-	return -1;
-}
+
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
@@ -1756,8 +1688,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 	struct omap_nand_platform_data	*pdata;
 	struct mtd_info			*mtd;
 	struct nand_chip		*nand_chip;
+	struct nand_ecclayout		*ecclayout;
 	int				err;
-	int				i, offset;
+	int				i;
 	dma_cap_mask_t			mask;
 	unsigned			sig;
 	struct resource			*res;
@@ -1840,6 +1773,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
+	/* check for small page devices */
+	if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
+		pr_err("small page devices are not supported\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+	}
+
 	/* re-populate low-level callbacks based on xfer modes */
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
@@ -1931,6 +1871,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* populate MTD interface based on ECC scheme */
+	nand_chip->ecc.layout	= &omap_oobinfo;
+	ecclayout		= &omap_oobinfo;
 	switch (pdata->ecc_opt) {
 	case OMAP_ECC_HAM1_CODE_HW:
 		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
@@ -1941,6 +1883,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.calculate        = omap_calculate_ecc;
 		nand_chip->ecc.hwctl            = omap_enable_hwecc;
 		nand_chip->ecc.correct          = omap_correct_data;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		if (nand_chip->options & NAND_BUSWIDTH_16)
+			ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH;
+		else
+			ecclayout->eccpos[0]	= 1;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		break;
 
 	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
@@ -1953,6 +1905,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap3_correct_data_bch;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
 		info->bch = init_bch(nand_chip->ecc.bytes,
 					nand_chip->ecc.strength,
@@ -1981,6 +1940,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
@@ -2004,6 +1970,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
 		nand_chip->ecc.correct		= omap3_correct_data_bch;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
 		info->bch = init_bch(nand_chip->ecc.bytes,
 					nand_chip->ecc.strength,
@@ -2038,6 +2011,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 			pr_err("nand: error: could not initialize ELM\n");
 			goto out_release_mem_region;
 		}
+		/* define ECC layout */
+		ecclayout->eccbytes		= nand_chip->ecc.bytes *
+							(mtd->writesize /
+							nand_chip->ecc.size);
+		ecclayout->eccpos[0]		= BADBLOCK_MARKER_LENGTH;
+		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
+							ecclayout->eccbytes;
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
@@ -2051,34 +2031,17 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
-
-		if (nand_chip->options & NAND_BUSWIDTH_16) {
-			offset = 2;
-		} else {
-			offset = 1;
-			nand_chip->badblock_pattern = &bb_descrip_flashbased;
-		}
-		omap_oobinfo.eccbytes = 3 * (mtd->writesize / 512);
-		for (i = 0; i < omap_oobinfo.eccbytes; i++)
-			omap_oobinfo.eccpos[i] = i+offset;
-
-		omap_oobinfo.oobfree->offset = offset + omap_oobinfo.eccbytes;
-		omap_oobinfo.oobfree->length = mtd->oobsize -
-					(offset + omap_oobinfo.eccbytes);
-
-		nand_chip->ecc.layout = &omap_oobinfo;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		/* build OOB layout for BCH ECC correction */
-		err = omap3_init_bch_tail(mtd);
-		if (err) {
-			err = -EINVAL;
-			goto out_release_mem_region;
-		}
+	/* populate remaining ECC layout data */
+	ecclayout->oobfree->length = mtd->oobsize - (BADBLOCK_MARKER_LENGTH +
+							ecclayout->eccbytes);
+	for (i = 1; i < ecclayout->eccbytes; i++)
+		ecclayout->eccpos[i] = ecclayout->eccpos[0] + i;
+	/* check if NAND device's OOB is enough to store ECC signatures */
+	if (mtd->oobsize < (ecclayout->eccbytes + BADBLOCK_MARKER_LENGTH)) {
+		pr_err("not enough OOB bytes required = %d, available=%d\n",
+					   ecclayout->eccbytes, mtd->oobsize);
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* second phase scan */
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:21 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:21 +0530
Subject: [PATCH v11 05/10] mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC
 configurations in device_probe
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-6-git-send-email-pekon@ti.com>

current implementation in omap3_init_bch() has some redundant code like:
(1) omap3_init_bch() re-probes the DT-binding to detect presence of ELM h/w
    engine on SoC. And based on that it selects implemetation of ecc-scheme.
    However, this is already done as part of GPMC DT parsing.
(2) As omap3_init_bch() serves as common function for configuring all types of
    BCHx ecc-schemes, so there are multiple levels of redudant if..then..else
    checks while populating nand_chip->ecc.

This patch make following changes to OMAP NAND driver:
(1) removes omap3_init_bch(): each ecc-scheme is individually configured in
    omap_nand_probe() there by removing redundant if..then..else checks.
(2) adds is_elm_present(): re-probing of ELM device via DT is not required as
    it's done in GPMC driver probe. Thus is_elm_present() just initializes ELM
    driver with NAND probe data, when ecc-scheme with h/w based error-detection
    is used.
(3) separates out configuration of different flavours of "BCH4" and "BCH8"
    ecc-schemes as given in below table
(4) conditionally compiles callbacks implementations of ecc.hwctl(),
    ecc.calculate(), ecc.correct() to avoid warning of un-used functions.

+---------------------------------------+---------------+---------------+
| ECC scheme                            |ECC calculation|Error detection|
+---------------------------------------+---------------+---------------+
|OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+
|OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
| (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
|                                       |               |               |
|OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
| (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
|        ti,elm-id)                     |               |               |
+---------------------------------------+---------------+---------------+

- 'CONFIG_MTD_NAND_ECC_BCH' is generic KConfig required to build lib/bch.c
    which is required for ECC error detection done in software.
    (mainly used for legacy platforms which do not have on-chip ELM engine)

- 'CONFIG_MTD_NAND_OMAP_BCH' is OMAP specific Kconfig to detemine presence
    on ELM h/w engine on SoC.

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 281 ++++++++++++++++++++++++++---------------------
 1 file changed, 158 insertions(+), 123 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index f464321..86ce48b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,10 +25,8 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 #include <linux/bch.h>
 #include <linux/platform_data/elm.h>
-#endif
 
 #include <linux/platform_data/mtd-nand-omap2.h>
 
@@ -141,6 +139,8 @@
 #define BCH_ECC_SIZE0		0x0	/* ecc_size0 = 0, no oob protection */
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
+#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
+
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
 	0xac, 0x6b, 0xff, 0x99, 0x7b};
@@ -182,14 +182,12 @@ struct omap_nand_info {
 	u_char				*buf;
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
+	/* fields specific for BCHx_HW ECC scheme */
 	struct bch_control             *bch;
 	struct nand_ecclayout           ecclayout;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
-#endif
 };
 
 /**
@@ -1058,8 +1056,7 @@ static int omap_dev_ready(struct mtd_info *mtd)
 	}
 }
 
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-
+#if defined(CONFIG_MTD_NAND_ECC_BCH) || defined(CONFIG_MTD_NAND_OMAP_BCH)
 /**
  * omap3_enable_hwecc_bch - Program OMAP3 GPMC to perform BCH ECC correction
  * @mtd: MTD device structure
@@ -1140,7 +1137,9 @@ static void omap3_enable_hwecc_bch(struct mtd_info *mtd, int mode)
 	/* Clear ecc and enable bits */
 	writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control);
 }
+#endif
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_calculate_ecc_bch4 - Generate 7 bytes of ECC bytes
  * @mtd: MTD device structure
@@ -1225,7 +1224,9 @@ static int omap3_calculate_ecc_bch8(struct mtd_info *mtd, const u_char *dat,
 
 	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap3_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:	MTD device structure
@@ -1517,7 +1518,9 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
+#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
  * omap3_correct_data_bch - Decode received data and correct errors
  * @mtd: MTD device structure
@@ -1549,7 +1552,9 @@ static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
 	}
 	return count;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1637,118 +1642,48 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
 }
 
 /**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
+ * is_elm_present - checks for presence of ELM module by scanning DT nodes
+ * @omap_nand_info: NAND device structure containing platform data
+ * @bch_type: 0x0=BCH4, 0x1=BCH8, 0x2=BCH16
  */
-static void omap3_free_bch(struct mtd_info *mtd)
+static int is_elm_present(struct omap_nand_info *info,
+			struct device_node *elm_node, enum bch_ecc bch_type)
 {
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
+	struct platform_device *pdev;
+	info->is_elm_used = false;
+	/* check whether elm-id is passed via DT */
+	if (!elm_node) {
+		pr_err("nand: error: ELM DT node not found\n");
+		return -ENODEV;
+	}
+	pdev = of_find_device_by_node(elm_node);
+	/* check whether ELM device is registered */
+	if (!pdev) {
+		pr_err("nand: error: ELM device not found\n");
+		return -ENODEV;
 	}
+	/* ELM module available, now configure it */
+	info->elm_dev = &pdev->dev;
+	if (elm_config(info->elm_dev, bch_type))
+		return -ENODEV;
+	info->is_elm_used = true;
+	return 0;
 }
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
+#ifdef CONFIG_MTD_NAND_ECC_BCH
 /**
- * omap3_init_bch - Initialize BCH ECC
+ * omap3_free_bch - Release BCH ecc resources
  * @mtd: MTD device structure
- * @ecc_opt: OMAP ECC mode (OMAP_ECC_BCH4_CODE_HW or OMAP_ECC_BCH8_CODE_HW)
  */
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
+static void omap3_free_bch(struct mtd_info *mtd)
 {
-	int max_errors;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 						   mtd);
-#ifdef CONFIG_MTD_NAND_OMAP_BCH8
-	const int hw_errors = BCH8_MAX_ERROR;
-#else
-	const int hw_errors = BCH4_MAX_ERROR;
-#endif
-	enum bch_ecc bch_type;
-	const __be32 *parp;
-	int lenp;
-	struct device_node *elm_node;
-
-	info->bch = NULL;
-
-	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);
-		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 = max_errors;
-
-	if (hw_errors == BCH8_MAX_ERROR)
-		bch_type = BCH8_ECC;
-	else
-		bch_type = BCH4_ECC;
-
-	/* Detect availability of ELM module */
-	parp = of_get_property(info->of_node, "elm_id", &lenp);
-	if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
-		pr_err("Missing elm_id property, fall back to Software BCH\n");
-		info->is_elm_used = false;
-	} else {
-		struct platform_device *pdev;
-
-		elm_node = of_find_node_by_phandle(be32_to_cpup(parp));
-		pdev = of_find_device_by_node(elm_node);
-		info->elm_dev = &pdev->dev;
-
-		if (elm_config(info->elm_dev, bch_type) == 0)
-			info->is_elm_used = true;
-	}
-
-	if (info->is_elm_used && (mtd->writesize <= 4096)) {
-
-		if (hw_errors == BCH8_MAX_ERROR)
-			info->nand.ecc.bytes = BCH8_SIZE;
-		else
-			info->nand.ecc.bytes = BCH4_SIZE;
-
-		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;
-	} else {
-		/*
-		 * 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;
-		}
+	if (info->bch) {
+		free_bch(info->bch);
+		info->bch = NULL;
 	}
-
-	pr_info("enabling NAND BCH ecc with %d-bit correction\n", max_errors);
-	return 0;
-fail:
-	omap3_free_bch(mtd);
-	return -1;
 }
 
 /**
@@ -1806,11 +1741,6 @@ fail:
 }
 
 #else
-static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt)
-{
-	pr_err("CONFIG_MTD_NAND_OMAP_BCH is not enabled\n");
-	return -1;
-}
 static int omap3_init_bch_tail(struct mtd_info *mtd)
 {
 	return -1;
@@ -1818,7 +1748,7 @@ static int omap3_init_bch_tail(struct mtd_info *mtd)
 static void omap3_free_bch(struct mtd_info *mtd)
 {
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
+#endif /* CONFIG_MTD_NAND_ECC_BCH */
 
 static int omap_nand_probe(struct platform_device *pdev)
 {
@@ -1851,15 +1781,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
+	info->bch		= NULL;
+	info->of_node		= pdata->of_node;
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN;
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
-	info->of_node		= pdata->of_node;
-#endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
@@ -2001,22 +1930,125 @@ static int omap_nand_probe(struct platform_device *pdev)
 		goto out_release_mem_region;
 	}
 
-	/* select the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAM1_CODE_HW) {
+	/* populate MTD interface based on ECC scheme */
+	switch (pdata->ecc_opt) {
+	case OMAP_ECC_HAM1_CODE_HW:
+		pr_info("nand: using OMAP_ECC_HAM1_CODE_HW\n");
+		nand_chip->ecc.mode             = NAND_ECC_HW;
 		nand_chip->ecc.bytes            = 3;
 		nand_chip->ecc.size             = 512;
 		nand_chip->ecc.strength         = 1;
 		nand_chip->ecc.calculate        = omap_calculate_ecc;
 		nand_chip->ecc.hwctl            = omap_enable_hwecc;
 		nand_chip->ecc.correct          = omap_correct_data;
-		nand_chip->ecc.mode             = NAND_ECC_HW;
-	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
-		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
-		err = omap3_init_bch(mtd, pdata->ecc_opt);
-		if (err) {
+		break;
+
+	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 7;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH4_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH4_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 7 + 1;
+		nand_chip->ecc.strength		= 4;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			err = -ENODEV;
 			goto out_release_mem_region;
 		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+#ifdef CONFIG_MTD_NAND_ECC_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		nand_chip->ecc.bytes		= 13;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
+		/* software bch library is used for locating errors */
+		info->bch = init_bch(nand_chip->ecc.bytes,
+					nand_chip->ecc.strength,
+					OMAP_ECC_BCH8_POLYNOMIAL);
+		if (!info->bch) {
+			pr_err("nand: error: unable to use s/w BCH library\n");
+			err = -EINVAL;
+			goto out_release_mem_region;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	case OMAP_ECC_BCH8_CODE_HW:
+#ifdef CONFIG_MTD_NAND_OMAP_BCH
+		pr_info("nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme\n");
+		nand_chip->ecc.mode		= NAND_ECC_HW;
+		nand_chip->ecc.size		= 512;
+		/* 14th bit is kept reserved for ROM-code compatibility */
+		nand_chip->ecc.bytes		= 13 + 1;
+		nand_chip->ecc.strength		= 8;
+		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
+		nand_chip->ecc.correct		= omap_elm_correct_data;
+		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch;
+		nand_chip->ecc.read_page	= omap_read_page_bch;
+		nand_chip->ecc.write_page	= omap_write_page_bch;
+		/* This ECC scheme requires ELM H/W block */
+		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
+			pr_err("nand: error: could not initialize ELM\n");
+			goto out_release_mem_region;
+		}
+		break;
+#else
+		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
+#endif
+
+	default:
+		pr_err("nand: error: invalid or unsupported ECC scheme\n");
+		err = -EINVAL;
+		goto out_release_mem_region;
 	}
 
 	/* rom code layout */
@@ -2038,6 +2070,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 		nand_chip->ecc.layout = &omap_oobinfo;
 	} else if ((pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW) ||
+		   (pdata->ecc_opt == OMAP_ECC_BCH4_CODE_HW_DETECTION_SW) ||
+		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW_DETECTION_SW) ||
 		   (pdata->ecc_opt == OMAP_ECC_BCH8_CODE_HW)) {
 		/* build OOB layout for BCH ECC correction */
 		err = omap3_init_bch_tail(mtd);
@@ -2070,6 +2104,7 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
+	omap3_free_bch(mtd);
 	kfree(info);
 
 	return err;
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:23 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:23 +0530
Subject: [PATCH v11 07/10] mtd: nand: omap: use drivers/mtd/nand/nand_bch.c
 wrapper for BCH ECC instead of lib/bch.c
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-8-git-send-email-pekon@ti.com>

generic frame-work in mtd/nand/nand_bch.c is a wrapper above lib/bch.h which
encapsulates all control information specific to BCH ecc algorithm in software.
Thus this patch:
(1) replace omap specific implementations with equivalent wrapper in nand_bch.c
    so that generic code from nand_bch.c is re-used. like;
        omap3_correct_data_bch() -> nand_bch_correct_data()
        omap3_free_bch() -> nand_bch_free()
(2) replace direct calls to lib/bch.c with wrapper functions defined in nand_bch.c
	init_bch() -> nand_bch_init()

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 96 +++++++++++-------------------------------------
 1 file changed, 22 insertions(+), 74 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index b6a08b2..93aa35c 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -25,7 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 
-#include <linux/bch.h>
+#include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
@@ -140,7 +140,6 @@
 #define BCH_ECC_SIZE1		0x20	/* ecc_size1 = 32 */
 
 #define BADBLOCK_MARKER_LENGTH		2
-#define OMAP_ECC_BCH8_POLYNOMIAL	0x201b
 
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 static u_char bch8_vector[] = {0xf3, 0xdb, 0x14, 0x16, 0x8b, 0xd2, 0xbe, 0xcc,
@@ -173,7 +172,6 @@ struct omap_nand_info {
 	int					buf_len;
 	struct gpmc_nand_regs		reg;
 	/* fields specific for BCHx_HW ECC scheme */
-	struct bch_control             *bch;
 	bool				is_elm_used;
 	struct device			*elm_dev;
 	struct device_node		*of_node;
@@ -1507,43 +1505,7 @@ static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,
 
 	return stat;
 }
-#endif /* CONFIG_MTD_NAND_OMAP_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_correct_data_bch - Decode received data and correct errors
- * @mtd: MTD device structure
- * @data: page data
- * @read_ecc: ecc read from nand flash
- * @calc_ecc: ecc read from HW ECC registers
- */
-static int omap3_correct_data_bch(struct mtd_info *mtd, u_char *data,
-				  u_char *read_ecc, u_char *calc_ecc)
-{
-	int i, count;
-	/* cannot correct more than 8 errors */
-	unsigned int errloc[8];
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-
-	count = decode_bch(info->bch, NULL, 512, read_ecc, calc_ecc, NULL,
-			   errloc);
-	if (count > 0) {
-		/* correct errors */
-		for (i = 0; i < count; i++) {
-			/* correct data only, not ecc bytes */
-			if (errloc[i] < 8*512)
-				data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
-			pr_debug("corrected bitflip %u\n", errloc[i]);
-		}
-	} else if (count < 0) {
-		pr_err("ecc unrecoverable error\n");
-	}
-	return count;
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
-#ifdef CONFIG_MTD_NAND_OMAP_BCH
 /**
  * omap_write_page_bch - BCH ecc based write page function for entire page
  * @mtd:		mtd info structure
@@ -1660,28 +1622,6 @@ static int is_elm_present(struct omap_nand_info *info,
 }
 #endif /* CONFIG_MTD_NAND_ECC_BCH */
 
-#ifdef CONFIG_MTD_NAND_ECC_BCH
-/**
- * omap3_free_bch - Release BCH ecc resources
- * @mtd: MTD device structure
- */
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-						   mtd);
-	if (info->bch) {
-		free_bch(info->bch);
-		info->bch = NULL;
-	}
-}
-
-#else
-
-static void omap3_free_bch(struct mtd_info *mtd)
-{
-}
-#endif /* CONFIG_MTD_NAND_ECC_BCH */
-
 static int omap_nand_probe(struct platform_device *pdev)
 {
 	struct omap_nand_info		*info;
@@ -1714,13 +1654,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
 	info->reg		= pdata->reg;
-	info->bch		= NULL;
 	info->of_node		= pdata->of_node;
 	mtd			= &info->mtd;
 	mtd->priv		= &info->nand;
 	mtd->name		= dev_name(&pdev->dev);
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
+	nand_chip->ecc.priv	= NULL;
 	nand_chip->options	|= NAND_SKIP_BBTSCAN;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1903,7 +1843,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 7;
 		nand_chip->ecc.strength		= 4;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch4;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1913,10 +1853,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		nand_chip->ecc.priv		= nand_bch_init(mtd,
+							nand_chip->ecc.size,
+							nand_chip->ecc.bytes,
+							&nand_chip->ecc.layout);
+		if (!nand_chip->ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 		}
@@ -1968,7 +1909,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.bytes		= 13;
 		nand_chip->ecc.strength		= 8;
 		nand_chip->ecc.hwctl		= omap3_enable_hwecc_bch;
-		nand_chip->ecc.correct		= omap3_correct_data_bch;
+		nand_chip->ecc.correct		= nand_bch_correct_data;
 		nand_chip->ecc.calculate	= omap3_calculate_ecc_bch8;
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1978,10 +1919,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 		ecclayout->oobfree->offset	= ecclayout->eccpos[0] +
 							ecclayout->eccbytes;
 		/* software bch library is used for locating errors */
-		info->bch = init_bch(nand_chip->ecc.bytes,
-					nand_chip->ecc.strength,
-					OMAP_ECC_BCH8_POLYNOMIAL);
-		if (!info->bch) {
+		nand_chip->ecc.priv		= nand_bch_init(mtd,
+							nand_chip->ecc.size,
+							nand_chip->ecc.bytes,
+							&nand_chip->ecc.layout);
+		if (!nand_chip->ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
 			goto out_release_mem_region;
@@ -2067,7 +2009,10 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
-	omap3_free_bch(mtd);
+	if (nand_chip->ecc.priv) {
+		nand_bch_free(nand_chip->ecc.priv);
+		nand_chip->ecc.priv = NULL;
+	}
 	kfree(info);
 
 	return err;
@@ -2079,7 +2024,10 @@ static int omap_nand_remove(struct platform_device *pdev)
 	struct nand_chip *nand_chip = mtd->priv;
 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
 							mtd);
-	omap3_free_bch(mtd);
+	if (nand_chip->ecc.priv) {
+		nand_bch_free(nand_chip->ecc.priv);
+		nand_chip->ecc.priv = NULL;
+	}
 
 	if (info->dma)
 		dma_release_channel(info->dma);
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:26 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:26 +0530
Subject: [PATCH v11 10/10] mtd: nand: omap: remove selection of BCH ecc-scheme
 via KConfig
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-11-git-send-email-pekon@ti.com>

With OMAP NAND driver updates, selection of ecc-scheme:
*DT enabled kernel*
 	depends on ti,nand-ecc-opt and ti,elm-id DT bindings.
*Non DT enabled kernel*
	depends on elm_dev and ecc-scheme passed along with platform-data
	from board file.

So, selection of ecc-scheme (BCH8 or BCH4) from KConfig can be removed

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/Kconfig | 40 ++++++----------------------------------
 1 file changed, 6 insertions(+), 34 deletions(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..93ae6a6 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -96,43 +96,15 @@ config MTD_NAND_OMAP2
 
 config MTD_NAND_OMAP_BCH
 	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
-	tristate "Enable support for hardware BCH error correction"
+	tristate "Support hardware based BCH error correction"
 	default n
 	select BCH
-	select BCH_CONST_PARAMS
 	help
-	 Support for hardware BCH error correction.
-
-choice
-	prompt "BCH error correction capability"
-	depends on MTD_NAND_OMAP_BCH
-
-config MTD_NAND_OMAP_BCH8
-	bool "8 bits / 512 bytes (recommended)"
-	help
-	 Support correcting up to 8 bitflips per 512-byte block.
-	 This will use 13 bytes of spare area per 512 bytes of page data.
-	 This is the recommended mode, as 4-bit mode does not work
-	 on some OMAP3 revisions, due to a hardware bug.
-
-config MTD_NAND_OMAP_BCH4
-	bool "4 bits / 512 bytes"
-	help
-	 Support correcting up to 4 bitflips per 512-byte block.
-	 This will use 7 bytes of spare area per 512 bytes of page data.
-	 Note that this mode does not work on some OMAP3 revisions, due to a
-	 hardware bug. Please check your OMAP datasheet before selecting this
-	 mode.
-
-endchoice
-
-if MTD_NAND_OMAP_BCH
-config BCH_CONST_M
-	default 13
-config BCH_CONST_T
-	default 4 if MTD_NAND_OMAP_BCH4
-	default 8 if MTD_NAND_OMAP_BCH8
-endif
+	  This config enables the ELM hardware engine, which can be used to
+	  locate and correct errors when using BCH ECC scheme. This offloads
+	  the cpu from doing ECC error searching and correction. However some
+	  legacy OMAP families like OMAP2xxx, OMAP3xxx do not have ELM engine
+	  so they should not enable this config symbol.
 
 config MTD_NAND_IDS
 	tristate
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:25 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:25 +0530
Subject: [PATCH v11 09/10] mtd: nand: omap: updated devm_xx for all resource
 allocation and free calls
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-10-git-send-email-pekon@ti.com>

"Managed Device Resource" or devm_xx calls takes care of automatic freeing
of the resource in case of:
- failure during driver probe
- failure during resource allocation
- detaching or unloading of driver module (rmmod)
Reference: Documentation/driver-model/devres.txt

Though OMAP NAND driver handles freeing of resource allocation in most of
the cases, but using devm_xx provides more clean and effortless approach
to handle all such cases.

- simplifies label for exiting probe during error
  s/out_release_mem_region/return_error

Signed-off-by: Pekon Gupta <pekon at ti.com>
---
 drivers/mtd/nand/omap2.c | 85 ++++++++++++++++++++----------------------------
 1 file changed, 35 insertions(+), 50 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 93aa35c..ec40b8d 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1642,7 +1642,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(struct omap_nand_info),
+				GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -1667,22 +1668,23 @@ static int omap_nand_probe(struct platform_device *pdev)
 	if (res == NULL) {
 		err = -EINVAL;
 		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto out_free_info;
+		goto return_error;
 	}
 
 	info->phys_base = res->start;
 	info->mem_size = resource_size(res);
 
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
+	if (!devm_request_mem_region(&pdev->dev, info->phys_base,
+				info->mem_size,	pdev->dev.driver->name)) {
 		err = -EBUSY;
-		goto out_free_info;
+		goto return_error;
 	}
 
-	nand_chip->IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
+	nand_chip->IO_ADDR_R = devm_ioremap(&pdev->dev, info->phys_base,
+						info->mem_size);
 	if (!nand_chip->IO_ADDR_R) {
 		err = -ENOMEM;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	nand_chip->controller = &info->controller;
@@ -1710,14 +1712,14 @@ static int omap_nand_probe(struct platform_device *pdev)
 	if (nand_scan_ident(mtd, 1, NULL)) {
 		pr_err("nand device scan failed, may be bus-width mismatch\n");
 		err = -ENXIO;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* check for small page devices */
 	if ((mtd->oobsize < 64) && (pdata->ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
 		pr_err("small page devices are not supported\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* re-populate low-level callbacks based on xfer modes */
@@ -1745,7 +1747,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (!info->dma) {
 			dev_err(&pdev->dev, "DMA engine request failed\n");
 			err = -ENXIO;
-			goto out_release_mem_region;
+			goto return_error;
 		} else {
 			struct dma_slave_config cfg;
 
@@ -1760,7 +1762,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 			if (err) {
 				dev_err(&pdev->dev, "DMA engine slave config failed: %d\n",
 					err);
-				goto out_release_mem_region;
+				goto return_error;
 			}
 			nand_chip->read_buf   = omap_read_buf_dma_pref;
 			nand_chip->write_buf  = omap_write_buf_dma_pref;
@@ -1772,30 +1774,32 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (info->gpmc_irq_fifo <= 0) {
 			dev_err(&pdev->dev, "error getting fifo irq\n");
 			err = -ENODEV;
-			goto out_release_mem_region;
+			goto return_error;
 		}
-		err = request_irq(info->gpmc_irq_fifo,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-fifo", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_fifo,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-fifo", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_fifo, err);
 			info->gpmc_irq_fifo = 0;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 
 		info->gpmc_irq_count = platform_get_irq(pdev, 1);
 		if (info->gpmc_irq_count <= 0) {
 			dev_err(&pdev->dev, "error getting count irq\n");
 			err = -ENODEV;
-			goto out_release_mem_region;
+			goto return_error;
 		}
-		err = request_irq(info->gpmc_irq_count,	omap_nand_irq,
-					IRQF_SHARED, "gpmc-nand-count", info);
+		err = devm_request_irq(&pdev->dev, info->gpmc_irq_count,
+					omap_nand_irq, IRQF_SHARED,
+					"gpmc-nand-count", info);
 		if (err) {
 			dev_err(&pdev->dev, "requesting irq(%d) error:%d",
 						info->gpmc_irq_count, err);
 			info->gpmc_irq_count = 0;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 
 		nand_chip->read_buf  = omap_read_buf_irq_pref;
@@ -1807,7 +1811,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev,
 			"xfer_type(%d) not supported!\n", pdata->xfer_type);
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* populate MTD interface based on ECC scheme */
@@ -1865,7 +1869,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	case OMAP_ECC_BCH4_CODE_HW:
@@ -1892,13 +1896,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (is_elm_present(info, pdata->elm_of_node, BCH4_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
 			err = -ENODEV;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
@@ -1926,13 +1930,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		if (!nand_chip->ecc.priv) {
 			pr_err("nand: error: unable to use s/w BCH library\n");
 			err = -EINVAL;
-			goto out_release_mem_region;
+			goto return_error;
 		}
 		break;
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_ECC_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	case OMAP_ECC_BCH8_CODE_HW:
@@ -1951,7 +1955,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		/* This ECC scheme requires ELM H/W block */
 		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
-			goto out_release_mem_region;
+			goto return_error;
 		}
 		/* define ECC layout */
 		ecclayout->eccbytes		= nand_chip->ecc.bytes *
@@ -1964,13 +1968,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 #else
 		pr_err("nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 #endif
 
 	default:
 		pr_err("nand: error: invalid or unsupported ECC scheme\n");
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* populate remaining ECC layout data */
@@ -1983,13 +1987,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 		pr_err("not enough OOB bytes required = %d, available=%d\n",
 					   ecclayout->eccbytes, mtd->oobsize);
 		err = -EINVAL;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	/* second phase scan */
 	if (nand_scan_tail(mtd)) {
 		err = -ENXIO;
-		goto out_release_mem_region;
+		goto return_error;
 	}
 
 	ppdata.of_node = pdata->of_node;
@@ -2000,21 +2004,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	return 0;
 
-out_release_mem_region:
+return_error:
 	if (info->dma)
 		dma_release_channel(info->dma);
-	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
-	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
-out_free_info:
 	if (nand_chip->ecc.priv) {
 		nand_bch_free(nand_chip->ecc.priv);
 		nand_chip->ecc.priv = NULL;
 	}
-	kfree(info);
-
 	return err;
 }
 
@@ -2028,20 +2024,9 @@ static int omap_nand_remove(struct platform_device *pdev)
 		nand_bch_free(nand_chip->ecc.priv);
 		nand_chip->ecc.priv = NULL;
 	}
-
 	if (info->dma)
 		dma_release_channel(info->dma);
-
-	if (info->gpmc_irq_count > 0)
-		free_irq(info->gpmc_irq_count, info);
-	if (info->gpmc_irq_fifo > 0)
-		free_irq(info->gpmc_irq_fifo, info);
-
-	/* Release NAND device, its internal structures and partitions */
 	nand_release(mtd);
-	iounmap(nand_chip->IO_ADDR_R);
-	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
 	return 0;
 }
 
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:50:24 2013
From: pekon at ti.com (Pekon Gupta)
Date: Thu, 24 Oct 2013 18:20:24 +0530
Subject: [PATCH v11 08/10] ARM: dts: AM33xx: updated default ECC scheme in
 nand-ecc-opt
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <1382619026-4182-9-git-send-email-pekon@ti.com>

Updated DTS to replace deprecated binding with newer values
Refer: Documentation/devicetree/bindings/mtd/gpmc-nand.txt

Signed-off-by: Pekon Gupta <pekon at ti.com>
Reviewed-by: Felipe Balbi <balbi at ti.com>
---
 arch/arm/boot/dts/am335x-evm.dts   | 3 +--
 arch/arm/boot/dts/omap3430-sdp.dts | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index e8ec875..1aee6ac 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -269,7 +269,6 @@
 				reg = <0 0 0>; /* CS0, offset 0 */
 				nand-bus-width = <8>;
 				ti,nand-ecc-opt = "bch8";
-				gpmc,device-nand = "true";
 				gpmc,device-width = <1>;
 				gpmc,sync-clk-ps = <0>;
 				gpmc,cs-on-ns = <0>;
@@ -296,7 +295,7 @@
 
 				#address-cells = <1>;
 				#size-cells = <1>;
-				elm_id = <&elm>;
+				ti,elm-id = <&elm>;
 
 				/* MTD partition table */
 				partition at 0 {
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index e2249bc..501f863 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -105,7 +105,7 @@
 		reg = <1 0 0x08000000>;
 		nand-bus-width = <8>;
 
-		ti,nand-ecc-opt = "sw";
+		ti,nand-ecc-opt = "ham1";
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <36>;
 		gpmc,cs-wr-off-ns = <36>;
-- 
1.8.1



From pekon at ti.com  Thu Oct 24 08:59:26 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Thu, 24 Oct 2013 12:59:26 +0000
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20131023144652.GI2458@localhost>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com> <20131023125516.GA2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A0CB@DBDE04.ent.ti.com>
 <20131023132457.GD2458@localhost> <20131023144652.GI2458@localhost>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2A783@DBDE04.ent.ti.com>

Hi Ezequiel,

> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> I won't be able to make too much progress without some help or without
> squeezing my brains out :P
> 
> Care to push some git branch on some random repo with DT support for
> the NAND cape in the Beaglebone?
> 
Apologies for delay, I was testing and preparing a newer version of patch-set..

Please find the beagle-bone DTS attached. However, consider this as RFC
only, as I'm waiting for current series which has some DT-binding updates
to get accepted first.

Commit log in the patch would also guide you for some board tweaks
for enabling NAND cape on beagle-bone (LT/white)..
(I have recently sent v11 of the patch series incorporating last few
 comments from Brian about nand_scan_ident().)


Thanks.. 
with regards, pekon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ARM-DTS-am335x-bone-enable-support-for-NAND-cape.patch
Type: application/octet-stream
Size: 5291 bytes
Desc: 0001-ARM-DTS-am335x-bone-enable-support-for-NAND-cape.patch
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131024/5b46baaa/attachment.obj>

From ezequiel.garcia at free-electrons.com  Thu Oct 24 09:07:04 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 10:07:04 -0300
Subject: [PATCH v10 04/10] mtd: nand: omap: fix device scan:
 NAND_CMD_READID, NAND_CMD_RESET, CMD_CMD_PARAM use only x8 bus
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2A783@DBDE04.ent.ti.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-5-git-send-email-pekon@ti.com>
 <20131022201624.GL23337@ld-irv-0074.broadcom.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA29DB8@DBDE04.ent.ti.com>
 <5267690C.9080005@gmail.com> <20131023125516.GA2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A0CB@DBDE04.ent.ti.com>
 <20131023132457.GD2458@localhost> <20131023144652.GI2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A783@DBDE04.ent.ti.com>
Message-ID: <20131024130703.GA9958@localhost>

Pekon,

On Thu, Oct 24, 2013 at 12:59:26PM +0000, Gupta, Pekon wrote:
> Hi Ezequiel,
> 
> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> > I won't be able to make too much progress without some help or without
> > squeezing my brains out :P
> > 
> > Care to push some git branch on some random repo with DT support for
> > the NAND cape in the Beaglebone?
> > 
> Apologies for delay, I was testing and preparing a newer version of patch-set..
> 
> Please find the beagle-bone DTS attached. However, consider this as RFC
> only, as I'm waiting for current series which has some DT-binding updates
> to get accepted first.
> 
> Commit log in the patch would also guide you for some board tweaks
> for enabling NAND cape on beagle-bone (LT/white)..
> (I have recently sent v11 of the patch series incorporating last few
>  comments from Brian about nand_scan_ident().)
> 

Thanks! I'll give this a try.

Anyway, for future reference, it's really easier for testers and
reviewers to just push the code in some public git repo (github? gitorious?).

This way I don't have to apply the patches from my mailbox,
but just checkout a branch...
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Thu Oct 24 09:52:59 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 10:52:59 -0300
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up of
 supported ECC schemes
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <20131024135258.GC9958@localhost>

Hi Pekon,

Just as suggestion, I think you should reconsider your 'upstream strategy'.

On Thu, Oct 24, 2013 at 06:20:16PM +0530, Pekon Gupta wrote:
[..]
> 
> Pekon Gupta (10):
>   ARM: OMAP2+: cleaned-up DT support of various ECC schemes
>   mtd: nand: omap: combine different flavours of 1-bit hamming ecc schemes
>   mtd: nand: omap: cleanup: replace local references with generic framework names

IMHO, this patch about the dobule nand_scan_ident():
>   mtd: nand: omap: use DT specified bus-width only for scanning NAND device

is a fix unrelated to this series and can be pushed independently.
Maybe you can try to send it as a one-patch fix?

>   mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in device_probe
>   mtd: nand: omap: clean-up ecc layout for BCH ecc schemes
>   mtd: nand: omap: use drivers/mtd/nand/nand_bch.c wrapper for BCH ECC instead of lib/bch.c
>   ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt

And also this patch:
>   mtd: nand: omap: updated devm_xx for all resource allocation and free calls

doesn't seem to belong to this series.

I think tou could send those two independently and ask Brian to merge them earlier
if appropriate.

But again, this is just a suggestion.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From annulen at yandex.ru  Thu Oct 24 10:12:22 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Thu, 24 Oct 2013 18:12:22 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <loom.20131023T201657-894@post.gmane.org>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <loom.20131023T201657-894@post.gmane.org>
Message-ID: <237221382623942@web21m.yandex.ru>



23.10.2013, 22:26, "Yann Collet" <yann.collet.73 at gmail.com>:
> UBIFS error (pid 4288): ubifs_decompress: cannot decompress 12 bytes,
> (...)
> ????????data size ?????12
> ????????data:
> ????????00000000: 1f 00 01 00 ff e8 50 00 00 00 00 00
>
> The compressed format is correct.
> It describes a flow of 00, of size ~500.
>
> So the problem seems more likely on the decompression side.
>
> Are you sure you are providing "12" as the "input size" parameter ? and that
> the "maximum output size" parameter is correctly provided ? (i.e. >= to
> original data size)
>

Decompression code in kernel[1] is heavily modified. In particular, lz4_uncompress
function (used in this case) does not have input size parameter at all,
while it's present in lz4_uncompress_unknownoutputsize.

[1] lib/lz4/lz4_decompress.c

-- 
Regards,
Konstantin


From annulen at yandex.ru  Thu Oct 24 11:15:23 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Thu, 24 Oct 2013 19:15:23 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <237221382623942@web21m.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <loom.20131023T201657-894@post.gmane.org> <237221382623942@web21m.yandex.ru>
Message-ID: <106621382627723@web13g.yandex.ru>



24.10.2013, 18:20, "Konstantin Tokarev" <annulen at yandex.ru>:
> 23.10.2013, 22:26, "Yann Collet" <yann.collet.73 at gmail.com>:
>
>> ?UBIFS error (pid 4288): ubifs_decompress: cannot decompress 12 bytes,
>> ?(...)
>> ?????????data size ?????12
>> ?????????data:
>> ?????????00000000: 1f 00 01 00 ff e8 50 00 00 00 00 00
>>
>> ?The compressed format is correct.
>> ?It describes a flow of 00, of size ~500.
>>
>> ?So the problem seems more likely on the decompression side.
>>
>> ?Are you sure you are providing "12" as the "input size" parameter ? and that
>> ?the "maximum output size" parameter is correctly provided ? (i.e. >= to
>> ?original data size)
>
> Decompression code in kernel[1] is heavily modified. In particular, lz4_uncompress
> function (used in this case) does not have input size parameter at all,
> while it's present in lz4_uncompress_unknownoutputsize.
>
> [1] lib/lz4/lz4_decompress.c

Attached patch to crypto API wrapper for lz4hc seems to fix the issue. I can save
and read files on LZ4HC-compressed volume, and I'm running on LZ4HC-compressed rootfs,
flashed from mkfs.ubifs generated image (patch by Elie De Brauwer). My software
works correctly.

Unfortunately, on my board LZ4HC-compressed UBIFS volume performs noticeable worse
than LZO, while still faster than zlib. I guess the reason is that CPU is no longer a
bottleneck for my system, but NAND speed.

Thank you all for your help!

-- 
Regards,
Konstantin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: crypto_lz4.patch
Type: text/x-diff
Size: 852 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131024/6aa18cfe/attachment.bin>

From computersforpeace at gmail.com  Thu Oct 24 12:41:44 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 09:41:44 -0700
Subject: UBIFS: assert failed in ubifs_tnc_next_ent
In-Reply-To: <20131024013150.GB23337@ld-irv-0074.broadcom.com>
References: <20131023220950.GW23337@ld-irv-0074.broadcom.com>
 <20131024013150.GB23337@ld-irv-0074.broadcom.com>
Message-ID: <20131024164144.GC23337@ld-irv-0074.broadcom.com>

On Wed, Oct 23, 2013 at 06:31:50PM -0700, Brian Norris wrote:
> I'll retry on 3.12-rc and with a few extra backported
> fixes on 3.8.

It looks like I was just missing a few upstream bugfixes. That's what I
get for not properly following -stable properly :(

With the additional backporting of these two commits, my filesystem
tests survived overnight:

  commit 2928f0d0c5ebd6c9605c0d98207a44376387c298
  Author: Adam Thomas <adamthomas1111 at gmail.com>
  Date:   Sat Feb 2 22:32:31 2013 +0000

      UBIFS: fix use of freed ubifs_orphan objects

  commit 8afd500cb52a5d00bab4525dd5a560d199f979b9
  Author: Adam Thomas <adamthomas1111 at gmail.com>
  Date:   Sat Feb 2 22:35:08 2013 +0000

      UBIFS: fix double free of ubifs_orphan objects

Sorry for the noise. I guess this is a lesson for others, though. Greg
KH isn't joking when he says "all users must upgrade"!

Brian


From computersforpeace at gmail.com  Thu Oct 24 13:07:54 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 10:07:54 -0700
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <5268DE0B.7040208@ti.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
 <20131024010619.GA23337@ld-irv-0074.broadcom.com>
 <5268B3B8.4090807@ti.com>
 <20131024073400.GA9863@norris.computersforpeace.net>
 <5268DE0B.7040208@ti.com>
Message-ID: <20131024170754.GA20061@ld-irv-0074.broadcom.com>

On Thu, Oct 24, 2013 at 02:14:59PM +0530, Sourav Poddar wrote:
> On Thursday 24 October 2013 01:04 PM, Brian Norris wrote:
> >I just submitted my cleanups which (among other things) fixes this bug.
> >I believe I CC'd you. Go ahead and review it, and if it works to your
> >liking, please just base your work on top of it. I'll apply some or all
> >of that series if no one objects.
> >
> Ok.

I'll push parts the reviewed parts of my patch series now, so you can
base off them. (I'm still open to comments on them, though.)

> >Do all parts that support quad read also support all the other quad
> >opcodes (like quad program)?
> >
> I have Spansion and Macronix flash with me.
> 
> For spansion,
> supported quad commands are:
> QOR(0x6b) which is what I am using.
> QIOR(0xeb)
> DDR QIOR(0xed)
> 
> For macronix,
> QOR(0x6b) which is what I am using.
> QIOR(0xeb)

So it seems there are flash which support quad read but not quad
program. So the flag I recommended (M25P80_QUAD) should be made specific
to quad read (M25P80_QUAD_READ) I guess, since we may support page
program eventually.

Brian


From computersforpeace at gmail.com  Thu Oct 24 13:17:29 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 10:17:29 -0700
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131024171729.GB20061@ld-irv-0074.broadcom.com>

On Wed, Oct 23, 2013 at 07:58:19PM -0700, Brian Norris wrote:
> This patch fixes two memory errors:
> 
> 1. During a probe failure (in mtd_device_parse_register?) the command
>    buffer would not be freed.
> 
> 2. The command buffer's size is determined based on the 'fast_read'
>    boolean, but the assignment of fast_read is made after this
>    allocation. Thus, the buffer may be allocated "too small".
> 
> To fix the first, just switch to the devres version of kzalloc.
> 
> To fix the second, increase MAX_CMD_SIZE unconditionally. It's not worth
> saving a byte to fiddle around with the conditions here.
> 
> This problem was reported by Yuhang Wang a while back.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Reported-by: Yuhang Wang <wangyuhang2014 at gmail.com>
> Cc: <stable at vger.kernel.org>

I pushed patches 1, 2, and 3 to l2-mtd.git (for Sourav's sake). I'll
wait a little while on the others. Comments are still welcome on the
whole series, though.

Brian


From ezequiel.garcia at free-electrons.com  Thu Oct 24 13:31:04 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 14:31:04 -0300
Subject: UBIFS: assert failed in ubifs_tnc_next_ent
In-Reply-To: <20131024164144.GC23337@ld-irv-0074.broadcom.com>
References: <20131023220950.GW23337@ld-irv-0074.broadcom.com>
 <20131024013150.GB23337@ld-irv-0074.broadcom.com>
 <20131024164144.GC23337@ld-irv-0074.broadcom.com>
Message-ID: <20131024173103.GA2500@localhost>

On Thu, Oct 24, 2013 at 09:41:44AM -0700, Brian Norris wrote:
> On Wed, Oct 23, 2013 at 06:31:50PM -0700, Brian Norris wrote:
> > I'll retry on 3.12-rc and with a few extra backported
> > fixes on 3.8.
> 
> It looks like I was just missing a few upstream bugfixes. That's what I
> get for not properly following -stable properly :(
> 
> With the additional backporting of these two commits, my filesystem
> tests survived overnight:
> 
>   commit 2928f0d0c5ebd6c9605c0d98207a44376387c298
>   Author: Adam Thomas <adamthomas1111 at gmail.com>
>   Date:   Sat Feb 2 22:32:31 2013 +0000
> 
>       UBIFS: fix use of freed ubifs_orphan objects
> 
>   commit 8afd500cb52a5d00bab4525dd5a560d199f979b9
>   Author: Adam Thomas <adamthomas1111 at gmail.com>
>   Date:   Sat Feb 2 22:35:08 2013 +0000
> 
>       UBIFS: fix double free of ubifs_orphan objects
> 
> Sorry for the noise. I guess this is a lesson for others, though. Greg
> KH isn't joking when he says "all users must upgrade"!
> 

Interesting findings and interesting lesson :-)

I'll keep this in mind and thanks for sharing your findings!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Thu Oct 24 13:39:12 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 10:39:12 -0700
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <5268E495.5010707@ti.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
 <5268E35C.2030000@ti.com> <5268E495.5010707@ti.com>
Message-ID: <20131024173912.GC20061@ld-irv-0074.broadcom.com>

On Thu, Oct 24, 2013 at 02:42:53PM +0530, Sourav Poddar wrote:
> On Thursday 24 October 2013 02:37 PM, Sourav Poddar wrote:
> >On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
> >>--- a/drivers/mtd/devices/m25p80.c
> >>+++ b/drivers/mtd/devices/m25p80.c
> >>@@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
> >>      flash->page_size = info->page_size;
> >>      flash->mtd.writebufsize = flash->page_size;
> >>
> >>-    flash->fast_read = false;
> >>-    if (np&&  of_property_read_bool(np, "m25p,fast-read"))
> >>+    if (np)
> >>+        /* If we were instantiated by DT, use it */
> >>+        flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
> >>+    else
> >>+        /* If we weren't instantiated by DT, default to fast-read */
> >>          flash->fast_read = true;
> >>
> >This comment is in sync with my quad read mode support patch on
> >the mtd list.
> >
> >Here, you are defaulting the fast read to be true.

It was already default true for non-DT case where
M25PXX_USE_FAST_READ=y. I believe my code is purely a refactoring of the
code, assuming M25PXX_USE_FAST_READ is always enabled (and removing the
Kconfig).

> >Once I add quad mode
> >on top of this, I will set flash->quad_read = true. So, we will have both
> >fast and quad read set(which will not be correct). So, it is
> >necessary to default to fast read ?

I think my patch is a correct refactoring by itself. Any problem your
quad read patch has with it would still be a problem without this patch.

So, without quad-read support, we should default to fast-read unless the
chip doesn't support it. I think this is reasonable.

Now, once you add quad-read, you need to have quad-read override
fast-read.

> Though, we will hit this scenario only for a non dt case. For dt
> case, things will be fine.

Yes, but we need to make sure things make sense for all cases.

> >>-#ifdef CONFIG_M25PXX_USE_FAST_READ
> >>-    flash->fast_read = true;
> >>-#endif
> >>+    /* Some devices cannot do fast-read, no matter what DT tells us */
> >>      if (info->flags&  M25P_NO_FR)
> >>          flash->fast_read = false;
> >>
> >

I just realized this: fast-read and quad-read are mutually exclusive, so
the field that is currently 'bool m25p.fast_read' could easily just become
an 'enum m25p.read_type' (with values M25P_READ_NORMAL, M25P_READ_FAST,
M25P_READ_QUAD). That may or may not help your quad read patch.

I can delay this patch until others have looked at it, if you'd like.
You can resubmit your quad read patch without this patch 4. (But I think
this patch will help clean up your patch slightly.)

Brian


From sourav.poddar at ti.com  Thu Oct 24 13:55:33 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 23:25:33 +0530
Subject: [PATCHv3 2/3] drivers: mtd: devices: Add quad read support.
In-Reply-To: <20131024170754.GA20061@ld-irv-0074.broadcom.com>
References: <1381332284-21822-1-git-send-email-sourav.poddar@ti.com>
 <1381332284-21822-3-git-send-email-sourav.poddar@ti.com>
 <20131024010619.GA23337@ld-irv-0074.broadcom.com> <5268B3B8.4090807@ti.com>
 <20131024073400.GA9863@norris.computersforpeace.net>
 <5268DE0B.7040208@ti.com> <20131024170754.GA20061@ld-irv-0074.broadcom.com>
Message-ID: <52695F15.8090309@ti.com>

Hi Brian,
On Thursday 24 October 2013 10:37 PM, Brian Norris wrote:
> On Thu, Oct 24, 2013 at 02:14:59PM +0530, Sourav Poddar wrote:
>> On Thursday 24 October 2013 01:04 PM, Brian Norris wrote:
>>> I just submitted my cleanups which (among other things) fixes this bug.
>>> I believe I CC'd you. Go ahead and review it, and if it works to your
>>> liking, please just base your work on top of it. I'll apply some or all
>>> of that series if no one objects.
>>>
>> Ok.
> I'll push parts the reviewed parts of my patch series now, so you can
> base off them. (I'm still open to comments on them, though.)
>
>>> Do all parts that support quad read also support all the other quad
>>> opcodes (like quad program)?
>>>
>> I have Spansion and Macronix flash with me.
>>
>> For spansion,
>> supported quad commands are:
>> QOR(0x6b) which is what I am using.
>> QIOR(0xeb)
>> DDR QIOR(0xed)
>>
>> For macronix,
>> QOR(0x6b) which is what I am using.
>> QIOR(0xeb)
> So it seems there are flash which support quad read but not quad
> program. So the flag I recommended (M25P80_QUAD) should be made specific
> to quad read (M25P80_QUAD_READ) I guess, since we may support page
> program eventually.
>
Sounds good. I will take care of this in my next version.


~Sourav
> Brian



From sourav.poddar at ti.com  Thu Oct 24 13:56:25 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 24 Oct 2013 23:26:25 +0530
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
In-Reply-To: <20131024171729.GB20061@ld-irv-0074.broadcom.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <20131024171729.GB20061@ld-irv-0074.broadcom.com>
Message-ID: <52695F49.20907@ti.com>

On Thursday 24 October 2013 10:47 PM, Brian Norris wrote:
> On Wed, Oct 23, 2013 at 07:58:19PM -0700, Brian Norris wrote:
>> This patch fixes two memory errors:
>>
>> 1. During a probe failure (in mtd_device_parse_register?) the command
>>     buffer would not be freed.
>>
>> 2. The command buffer's size is determined based on the 'fast_read'
>>     boolean, but the assignment of fast_read is made after this
>>     allocation. Thus, the buffer may be allocated "too small".
>>
>> To fix the first, just switch to the devres version of kzalloc.
>>
>> To fix the second, increase MAX_CMD_SIZE unconditionally. It's not worth
>> saving a byte to fiddle around with the conditions here.
>>
>> This problem was reported by Yuhang Wang a while back.
>>
>> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
>> Reported-by: Yuhang Wang<wangyuhang2014 at gmail.com>
>> Cc:<stable at vger.kernel.org>
> I pushed patches 1, 2, and 3 to l2-mtd.git (for Sourav's sake).
Thanks!
> I'll
> wait a little while on the others. Comments are still welcome on the
> whole series, though.
>
> Brian



From computersforpeace at gmail.com  Thu Oct 24 14:29:51 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 11:29:51 -0700
Subject: [PATCH v2] flash_erase: check the nand type
In-Reply-To: <1382612391-13036-1-git-send-email-b32955@freescale.com>
References: <1382612391-13036-1-git-send-email-b32955@freescale.com>
Message-ID: <20131024182951.GD20061@ld-irv-0074.broadcom.com>

On Thu, Oct 24, 2013 at 06:59:51PM +0800, Huang Shijie wrote:
> Now, the MTD_NANDFLASH stands for SLC nand, and the MTD_MLCNANDFLASH
> stands for the MLC nand.
> 
> This patch includes the stdbool.h, and changes the "isNAND" to boolean type,
> and checks the right nand type for the MLC and SLC nand.
> 
> If the user wants to format a MLC nand for JFFS2, we will print out a message
> to warn him, and exit right now.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>

Thanks for the update. Pushed to mtd-utils.git.

BTW, this is not a problem with your patch, but MLC typically have large
OOB sizes which have outgrown the outdated ioctl(MEMGETOOBSEL), so
--jffs2 would have broken for them anyway. I just tested this on my
system. On an old kernel (where MLC is still detected as MTD_NANDFLASH)
I get:

  # flash_erase -j /dev/mtd1 0 1 
  flash_erase: error!: /dev/mtd1: unable to get NAND oobinfo
               error 22 (Invalid argument)

There's not much we can do about this.

Brian


From sourav.poddar at ti.com  Thu Oct 24 14:48:58 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 25 Oct 2013 00:18:58 +0530
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <20131024173912.GC20061@ld-irv-0074.broadcom.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
 <5268E35C.2030000@ti.com> <5268E495.5010707@ti.com>
 <20131024173912.GC20061@ld-irv-0074.broadcom.com>
Message-ID: <52696B9A.4070505@ti.com>

On Thursday 24 October 2013 11:09 PM, Brian Norris wrote:
> On Thu, Oct 24, 2013 at 02:42:53PM +0530, Sourav Poddar wrote:
>> On Thursday 24 October 2013 02:37 PM, Sourav Poddar wrote:
>>> On Thursday 24 October 2013 08:28 AM, Brian Norris wrote:
>>>> --- a/drivers/mtd/devices/m25p80.c
>>>> +++ b/drivers/mtd/devices/m25p80.c
>>>> @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
>>>>       flash->page_size = info->page_size;
>>>>       flash->mtd.writebufsize = flash->page_size;
>>>>
>>>> -    flash->fast_read = false;
>>>> -    if (np&&   of_property_read_bool(np, "m25p,fast-read"))
>>>> +    if (np)
>>>> +        /* If we were instantiated by DT, use it */
>>>> +        flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
>>>> +    else
>>>> +        /* If we weren't instantiated by DT, default to fast-read */
>>>>           flash->fast_read = true;
>>>>
>>> This comment is in sync with my quad read mode support patch on
>>> the mtd list.
>>>
>>> Here, you are defaulting the fast read to be true.
> It was already default true for non-DT case where
> M25PXX_USE_FAST_READ=y. I believe my code is purely a refactoring of the
> code, assuming M25PXX_USE_FAST_READ is always enabled (and removing the
> Kconfig).
>
>>> Once I add quad mode
>>> on top of this, I will set flash->quad_read = true. So, we will have both
>>> fast and quad read set(which will not be correct). So, it is
>>> necessary to default to fast read ?
> I think my patch is a correct refactoring by itself. Any problem your
> quad read patch has with it would still be a problem without this patch.
>
True, my bad I didn't realise that for internal testing I disable
fast read option in menuconfig.
> So, without quad-read support, we should default to fast-read unless the
> chip doesn't support it. I think this is reasonable.
>
> Now, once you add quad-read, you need to have quad-read override
> fast-read.
>
>> Though, we will hit this scenario only for a non dt case. For dt
>> case, things will be fine.
> Yes, but we need to make sure things make sense for all cases.
>
Yes.
>>>> -#ifdef CONFIG_M25PXX_USE_FAST_READ
>>>> -    flash->fast_read = true;
>>>> -#endif
>>>> +    /* Some devices cannot do fast-read, no matter what DT tells us */
>>>>       if (info->flags&   M25P_NO_FR)
>>>>           flash->fast_read = false;
>>>>
> I just realized this: fast-read and quad-read are mutually exclusive, so
> the field that is currently 'bool m25p.fast_read' could easily just become
correct.
> an 'enum m25p.read_type' (with values M25P_READ_NORMAL, M25P_READ_FAST,
> M25P_READ_QUAD). That may or may not help your quad read patch.
>
> I can delay this patch until others have looked at it, if you'd like.
> You can resubmit your quad read patch without this patch 4. (But I think
> this patch will help clean up your patch slightly.)
Ok. I will include this patch and try to cleanup.
> Brian



From martinez.javier at gmail.com  Thu Oct 24 15:49:09 2013
From: martinez.javier at gmail.com (Javier Martinez Canillas)
Date: Thu, 24 Oct 2013 21:49:09 +0200
Subject: [PATCH v10 10/10] mtd: nand: omap: remove selection of BCH
 ecc-scheme via KConfig
In-Reply-To: <20131023141352.GG2458@localhost>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-11-git-send-email-pekon@ti.com>
 <20131023134450.GE2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A130@DBDE04.ent.ti.com>
 <20131023141352.GG2458@localhost>
Message-ID: <CAAwP0s0M=KruCVUana+5Nfm-0nkMGTg1OAatKzCrDeHOXuqd6A@mail.gmail.com>

Hi Ezequiel

On Wed, Oct 23, 2013 at 4:13 PM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> Pekon,
>
> On Wed, Oct 23, 2013 at 01:55:58PM +0000, Gupta, Pekon wrote:
>> >
>> > I'm wondering how are you testing this in your SOC_AM33XX board (which
>> > is not ARCH_OMAP3). You probably have ARCH_OMAP3 always selected?
>> >
>> Yes, omap2plus_defconfig is a super set..
>> arch/arm/configs/omap2plus_defconfig automatically enables ARCH_OMAP3.
>>
>
> Yes, but I always remove what I won't use to reduce build time.
>
> And  now that you bring this issue. IMHO, the AM33xx family is going
> to be more and more widely used, so maybe introducing an am33xx_defconfig
> makes sense.
>
> Or is the trend to have the least possible amount of defconfigs?

I'm not familiar with AM33xx so I don't know how similar is to OMAP3
but we used to have different defconfigs for each OMAP board before
and consolidated everything in only two defconfigs: omap1_defconfig to
be used for all OMAP1 devices and omap2plus_defconfig to be used for
all OMAP2+ (i.e: OMAP{2,3,4,5}) devices.

Those have all the common kconfig options and board vendors can
customize to fit their needs and have a delta with something like:

$ ./scripts/kconfig/merge_config.sh
arch/arm/configs/omap2plus_defconfig /foo/bar/igep_defconfig

Again I'm not familiar with AM33xx but what I do know is that we
should keep defconfigs to a minimum.

> --
> Ezequiel Garc?a, Free Electrons
> Embedded Linux, Kernel and Android Engineering
> http://free-electrons.com
> --

Best regards,
Javier


From ezequiel.garcia at free-electrons.com  Thu Oct 24 16:05:57 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 17:05:57 -0300
Subject: [PATCH v10 10/10] mtd: nand: omap: remove selection of BCH
 ecc-scheme via KConfig
In-Reply-To: <CAAwP0s0M=KruCVUana+5Nfm-0nkMGTg1OAatKzCrDeHOXuqd6A@mail.gmail.com>
References: <1382172254-12448-1-git-send-email-pekon@ti.com>
 <1382172254-12448-11-git-send-email-pekon@ti.com>
 <20131023134450.GE2458@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2A130@DBDE04.ent.ti.com>
 <20131023141352.GG2458@localhost>
 <CAAwP0s0M=KruCVUana+5Nfm-0nkMGTg1OAatKzCrDeHOXuqd6A@mail.gmail.com>
Message-ID: <20131024200556.GA2520@localhost>

Javier,

On Thu, Oct 24, 2013 at 09:49:09PM +0200, Javier Martinez Canillas wrote:
> Hi Ezequiel
> 
> On Wed, Oct 23, 2013 at 4:13 PM, Ezequiel Garcia
> <ezequiel.garcia at free-electrons.com> wrote:
> > Pekon,
> >
> > On Wed, Oct 23, 2013 at 01:55:58PM +0000, Gupta, Pekon wrote:
> >> >
> >> > I'm wondering how are you testing this in your SOC_AM33XX board (which
> >> > is not ARCH_OMAP3). You probably have ARCH_OMAP3 always selected?
> >> >
> >> Yes, omap2plus_defconfig is a super set..
> >> arch/arm/configs/omap2plus_defconfig automatically enables ARCH_OMAP3.
> >>
> >
> > Yes, but I always remove what I won't use to reduce build time.
> >
> > And  now that you bring this issue. IMHO, the AM33xx family is going
> > to be more and more widely used, so maybe introducing an am33xx_defconfig
> > makes sense.
> >
> > Or is the trend to have the least possible amount of defconfigs?
> 
> I'm not familiar with AM33xx so I don't know how similar is to OMAP3
> but we used to have different defconfigs for each OMAP board before
> and consolidated everything in only two defconfigs: omap1_defconfig to
> be used for all OMAP1 devices and omap2plus_defconfig to be used for
> all OMAP2+ (i.e: OMAP{2,3,4,5}) devices.
> 
> Those have all the common kconfig options and board vendors can
> customize to fit their needs and have a delta with something like:
> 
> $ ./scripts/kconfig/merge_config.sh
> arch/arm/configs/omap2plus_defconfig /foo/bar/igep_defconfig
> 
> Again I'm not familiar with AM33xx but what I do know is that we
> should keep defconfigs to a minimum.
> 

Fair enough.

It's just a bit annoying to have a bigger-than-minimal kernel,
and I get tired of stripping the options.

But I can't ask the kernel to hold my favorite picks either:
we have enough churn already ;-)
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Thu Oct 24 17:27:15 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 18:27:15 -0300
Subject: [PATCH v11 04/10] mtd: nand: omap: use DT specified bus-width
 only for scanning NAND device
In-Reply-To: <1382619026-4182-5-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <1382619026-4182-5-git-send-email-pekon@ti.com>
Message-ID: <20131024212714.GB2520@localhost>

On Thu, Oct 24, 2013 at 06:20:20PM +0530, Pekon Gupta wrote:
> This patch:
> - calls nand_scan_ident() using bus-width as passed by DT
> - removes double calls to nand_scan_ident(), incase first call fails
>   then omap_nand_probe just returns error.
> 
> Signed-off-by: Pekon Gupta <pekon at ti.com>
> ---
>  drivers/mtd/nand/omap2.c | 21 +++++++++------------
>  1 file changed, 9 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index 5596368..f464321 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct platform_device *pdev)
>  	mtd->name		= dev_name(&pdev->dev);
>  	mtd->owner		= THIS_MODULE;
>  	nand_chip		= &info->nand;
> -	nand_chip->options	= pdata->devsize;
>  	nand_chip->options	|= NAND_SKIP_BBTSCAN;
>  #ifdef CONFIG_MTD_NAND_OMAP_BCH
>  	info->of_node		= pdata->of_node;
> @@ -1904,6 +1903,15 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->chip_delay = 50;
>  	}
>  
> +	/* scan NAND device connected to chip controller */
> +	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;

Hm.. this only works if the device is listed in nand_flash_ids[] array,
so that ONFI detection is not used. To make ONFI detection work I think you
need to do as Brian suggested and use NAND_BUSWIDTH_AUTO.

(Odd: why is there no current user of that auto-width option?)

Anyway, I really think we should fix this now and independently
of the evolution of this ECC DT binding discussion.
That way you can keep sending a smaller ECC DT binding patchset and
make reviewers focus on what's really important in each case.

I have a few fixes (based on your work) and I'll send them now, after
I complete the tests. We can continue our discussion there.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:12:12 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:12:12 -0300
Subject: [PATCH 0/5] Assorted OMAP2 NAND clean-ups
Message-ID: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>

Hello everyone,

As it was discussed recently in the mailing list, the omap2-nand driver currently
has an issue preventing proper ONFI detection of 16-bit devices (other drivers
may suffer from this same issue).

In an attempt to address such issue, patch 2/5 "mtd: nand: omap2: Fix device
detection path" uses NAND_BUSWIDTH_AUTO (actually discarding any DT property)
and leaves the bus width detection the NAND core code.

I've based the patch in previously sent work by Pekon Gupta, did some work and
added my name on it. I hope it's fine to handle the authorship like this.
Otherwise, feel free to tell.

This has been tested in a Beaglebone black (AM335x) board with a 16-bit Micron
NAND device, both ONFI and array-based detections work fine:

[    1.253200] omap-gpmc 50000000.gpmc: GPMC revision 6.0
[    1.260638] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron MT29F4G16ABADAH4)
[    1.269110] NAND device: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.275721] Missing elm_id property, fall back to Software BCH
[    1.283546] enabling NAND BCH ecc with 8-bit correction
[    1.290219] 8 ofpart partitions found on MTD device omap2-nand.0
[    1.296591] Creating 8 MTD partitions on "omap2-nand.0":
[    1.302192] 0x000000000000-0x000000020000 : "SPL1"
[    1.309884] 0x000000020000-0x000000040000 : "SPL2"
[    1.316332] 0x000000040000-0x000000060000 : "SPL3"
[    1.322599] 0x000000060000-0x000000080000 : "SPL4"
[    1.328877] 0x000000080000-0x000000260000 : "U-boot"
[    1.336763] 0x000000260000-0x000000280000 : "environment"
[    1.343575] 0x000000280000-0x000000780000 : "Kernel"
[    1.354074] 0x000000780000-0x000010000000 : "File-System"

Also, a quick run of nandtest ends successfully:

$ nandtest /dev/mtd7
ECC corrections: 0
ECC failures   : 0
Bad blocks     : 2
BBT blocks     : 0
Bad block at 0x00000000
Bad block at 0x00520000
[...]
Finished pass 1 successfully

The first patch 1/5 is included just for reference of the DT GPMC configuration
currently in use, together with required pinmuxing, in case anyone feels like
testing. It's not intended to be merged, since it doesn't belong to the Beaglebone
board itself, but instead it's an attached daughter board.

The other patches are just minor cleanups I came across while looking at the code.
As usual, the patchset applies on top of latest l2-mtd's master branch.

Pekon, Brian: Do you think this solution might work for 8-bit and 16-bit devices?

Feel free to comment or provide any feedback!

Ezequiel Garcia (3):
  mtd: nand: omap2: Fix OMAP_BCH option dependency
  mtd: nand: omap2: Use devm_kzalloc
  mtd: nand: omap2: Use devm_ioremap_resource

Pekon Gupta (2):
  ARM: am335x-bone: Add support for 16-bit NAND cape
  mtd: nand: omap2: Fix device detection path

 arch/arm/boot/dts/am335x-bone-common.dtsi | 28 ++++++++++++
 arch/arm/boot/dts/am335x-bone.dts         | 75 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/am335x-boneblack.dts    | 69 ++++++++++++++++++++++++++++
 drivers/mtd/nand/Kconfig                  |  2 +-
 drivers/mtd/nand/omap2.c                  | 52 +++++----------------
 5 files changed, 185 insertions(+), 41 deletions(-)

-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:12:13 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:12:13 -0300
Subject: [PATCH 1/5] ARM: am335x-bone: Add support for 16-bit NAND cape
In-Reply-To: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382652737-20239-2-git-send-email-ezequiel.garcia@free-electrons.com>

From: Pekon Gupta <pekon at ti.com>

Add GPMC timing configurations and NAND partitions for the Beaglebone
"NAND cape". Further information and datasheets of this cape can be found at:
- http://beagleboardtoys.info/index.php?title=BeagleBone_Memory_Expansion
- http://beagleboardtoys.info/index.php?title=BeagleBone_4Gb_16-Bit_NAND_Module

Signed-off-by: Pekon Gupta <pekon at ti.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
This patch is not really intended for inclusion. I'm just adding it
to the series for reference and in case anyone wants to test.

 arch/arm/boot/dts/am335x-bone-common.dtsi | 28 ++++++++++++
 arch/arm/boot/dts/am335x-bone.dts         | 75 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/am335x-boneblack.dts    | 69 ++++++++++++++++++++++++++++
 3 files changed, 172 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 2f66ded..73dcc58 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -107,6 +107,34 @@
 				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
 			>;
 		};
+
+		nandflash_pins_s0: nandflash_pins_s0 {
+			pinctrl-single,pins = <
+				0x0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+				0x4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+				0x8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+				0xc (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+				0x10 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+				0x14 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+				0x18 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+				0x1c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+				0x20 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad8.gpmc_ad8 */
+				0x24 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad9.gpmc_ad9 */
+				0x28 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad10.gpmc_ad10 */
+				0x2c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad11.gpmc_ad11 */
+				0x30 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad12.gpmc_ad12 */
+				0x34 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad13.gpmc_ad13 */
+				0x38 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad14.gpmc_ad14 */
+				0x3c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad15.gpmc_ad15 */
+				0x70 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+				0x74 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_wpn.gpio0_30 */
+				0x7c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_csn0.gpmc_csn0  */
+				0x90 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_advn_ale.gpmc_advn_ale */
+				0x94 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_oen_ren.gpmc_oen_ren */
+				0x98 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_wen.gpmc_wen */
+				0x9c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_be0n_cle.gpmc_be0n_cle */
+			>;
+		};
 	};
 
 	ocp {
diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
index 7993c48..d9172c7 100644
--- a/arch/arm/boot/dts/am335x-bone.dts
+++ b/arch/arm/boot/dts/am335x-bone.dts
@@ -9,3 +9,78 @@
 
 #include "am33xx.dtsi"
 #include "am335x-bone-common.dtsi"
+
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	nand at 0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+		gpmc,device-width = <2>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <740>;
+		gpmc,cs-wr-off-ns = <740>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <740>;
+		gpmc,adv-wr-off-ns = <740>;
+		gpmc,we-on-ns = <90>;
+		gpmc,we-off-ns = <600>;
+		gpmc,oe-on-ns = <150>;
+		gpmc,oe-off-ns = <650>;
+		gpmc,access-ns = <560>;
+		gpmc,rd-cycle-ns = <740>;
+		gpmc,wr-cycle-ns = <740>;
+		gpmc,wait-on-read = "true";
+		gpmc,wait-on-write = "true";
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ti,elm-id = <&elm>;
+		/* MTD partition table */
+		partition at 0 {
+			label = "SPL1";
+			reg = <0x00000000 0x000020000>;
+		};
+		partition at 1 {
+			label = "SPL2";
+			reg = <0x00020000 0x00020000>;
+		};
+		partition at 2 {
+			label = "SPL3";
+			reg = <0x00040000 0x00020000>;
+		};
+		partition at 3 {
+			label = "SPL4";
+			reg = <0x00060000 0x00020000>;
+		};
+		partition at 4 {
+			label = "U-boot";
+			reg = <0x00080000 0x001e0000>;
+		};
+		partition at 5 {
+			label = "environment";
+			reg = <0x00260000 0x00020000>;
+		};
+		partition at 6 {
+			label = "Kernel";
+			reg = <0x00280000 0x00500000>;
+		};
+		partition at 7 {
+			label = "File-System";
+			reg = <0x00780000 0x0F880000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
index 197cadf..e30f58a 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -15,3 +15,72 @@
 	regulator-max-microvolt = <1800000>;
 	regulator-always-on;
 };
+
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	nand at 0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+
+		gpmc,device-width = <2>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ti,elm-id = <&elm>;
+		/* MTD partition table */
+		partition at 0 {
+			label = "SPL1";
+			reg = <0x00000000 0x000020000>;
+		};
+		partition at 1 {
+			label = "SPL2";
+			reg = <0x00020000 0x00020000>;
+		};
+		partition at 2 {
+			label = "SPL3";
+			reg = <0x00040000 0x00020000>;
+		};
+		partition at 3 {
+			label = "SPL4";
+			reg = <0x00060000 0x00020000>;
+		};
+		partition at 4 {
+			label = "U-boot";
+			reg = <0x00080000 0x001e0000>;
+		};
+		partition at 5 {
+			label = "environment";
+			reg = <0x00260000 0x00020000>;
+		};
+		partition at 6 {
+			label = "Kernel";
+			reg = <0x00280000 0x00500000>;
+		};
+		partition at 7 {
+			label = "File-System";
+			reg = <0x00780000 0x0F880000>;
+		};
+	};
+};
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:12:15 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:12:15 -0300
Subject: [PATCH 3/5] mtd: nand: omap2: Fix OMAP_BCH option dependency
In-Reply-To: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382652737-20239-4-git-send-email-ezequiel.garcia@free-electrons.com>

This option does not need to depend in MTD_NAND, for it's enclosed
under it. Also, it's wrong to make it depend in ARCH_OMAP3 only
since the controller is used in a wider range of SoCs.

Instead, just leave the dependency on the OMAP2 driver option.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..8187466 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
 	  platforms.
 
 config MTD_NAND_OMAP_BCH
-	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
+	depends on MTD_NAND_OMAP2
 	tristate "Enable support for hardware BCH error correction"
 	default n
 	select BCH
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:12:14 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:12:14 -0300
Subject: [PATCH 2/5] mtd: nand: omap2: Fix device detection path
In-Reply-To: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382652737-20239-3-git-send-email-ezequiel.garcia@free-electrons.com>

From: Pekon Gupta <pekon at ti.com>

Because the device bus can be 8-bit or 16-bit width, yet ONFI detection
cannot work in 16-bit mode, we need to set the NAND_BUSWIDTH_AUTO option
which allows proper initialization configuration.

Once the bus width is detected, nand_scan_ident() updates the nand_chip struct
'option' field to use the appropriate read/write functions and configure
the ECC engine.

Signed-off-by: Pekon Gupta <pekon at ti.com>
[rebased and clean-up a bit pekon's original work]
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..e01a936 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1855,8 +1855,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->mtd.name		= dev_name(&pdev->dev);
 	info->mtd.owner		= THIS_MODULE;
 
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
+	info->nand.options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
 #endif
@@ -1903,6 +1902,10 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->nand.chip_delay = 50;
 	}
 
+	err = nand_scan_ident(&info->mtd, 1, NULL);
+	if (err < 0)
+		goto out_release_mem_region;
+
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		info->nand.read_buf   = omap_read_buf_pref;
@@ -2013,17 +2016,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
-			err = -ENXIO;
-			goto out_release_mem_region;
-		}
-	}
-
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:12:16 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:12:16 -0300
Subject: [PATCH 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382652737-20239-5-git-send-email-ezequiel.garcia@free-electrons.com>

This simplifies the error path and makes the code less error-prone.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index e01a936..d4cafb0 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1837,7 +1837,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -2066,9 +2066,6 @@ out_release_mem_region:
 	if (info->gpmc_irq_fifo > 0)
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
-out_free_info:
-	kfree(info);
-
 	return err;
 }
 
@@ -2091,7 +2088,6 @@ static int omap_nand_remove(struct platform_device *pdev)
 	nand_release(&info->mtd);
 	iounmap(info->nand.IO_ADDR_R);
 	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
 	return 0;
 }
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:12:17 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:12:17 -0300
Subject: [PATCH 5/5] mtd: nand: omap2: Use devm_ioremap_resource
In-Reply-To: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382652737-20239-6-git-send-email-ezequiel.garcia@free-electrons.com>

This simplifies the code and makes it less error-prone.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 30 +++++++-----------------------
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index d4cafb0..c11e831 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1830,6 +1830,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	unsigned sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
+	void __iomem			*base;
 
 	pdata = dev_get_platdata(&pdev->dev);
 	if (pdata == NULL) {
@@ -1861,29 +1862,15 @@ static int omap_nand_probe(struct platform_device *pdev)
 #endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		err = -EINVAL;
-		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto out_free_info;
-	}
-
-	info->phys_base = res->start;
-	info->mem_size = resource_size(res);
-
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
-		err = -EBUSY;
-		goto out_free_info;
-	}
-
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
-	if (!info->nand.IO_ADDR_R) {
-		err = -ENOMEM;
-		goto out_release_mem_region;
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		err = PTR_ERR(base);
+		return err;
 	}
 
 	info->nand.controller = &info->controller;
 
+	info->nand.IO_ADDR_R = base;
 	info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
 	info->nand.cmd_ctrl  = omap_hwcontrol;
 
@@ -1904,7 +1891,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	err = nand_scan_ident(&info->mtd, 1, NULL);
 	if (err < 0)
-		goto out_release_mem_region;
+		return err;
 
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
@@ -2065,7 +2052,6 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_count, info);
 	if (info->gpmc_irq_fifo > 0)
 		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
 	return err;
 }
 
@@ -2086,8 +2072,6 @@ 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, info->mem_size);
 	return 0;
 }
 
-- 
1.8.1.5



From computersforpeace at gmail.com  Thu Oct 24 18:15:36 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 15:15:36 -0700
Subject: [PATCH v3] mtd: nand: pxa3xx: Fix registered MTD name
In-Reply-To: <1382217565-11312-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382217565-11312-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131024221536.GE20061@ld-irv-0074.broadcom.com>

On Sat, Oct 19, 2013 at 06:19:25PM -0300, Ezequiel Garcia wrote:
> In a recent commit:
> 
>   commit f455578dd961087a5cf94730d9f6489bb1d355f0
>   Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
>   Date:   Mon Aug 12 14:14:53 2013 -0300
> 
>   mtd: nand: pxa3xx: Remove hardcoded mtd name
> 
>   There's no advantage in using a hardcoded name for the mtd device.
>   Instead use the provided by the platform_device.
> 
> The MTD name was changed to use the one provided by the platform_device.
> However, this can be problematic as some users want to set partitions
> using the kernel parameter 'mtdparts', where the name is needed.
> 
> Therefore, to avoid regressions in users relying in 'mtdparts' we revert
> the change and use the previous one 'pxa3xx_nand-0'.
> 
> While at it, let's put a big comment and prevent this change from happening
> ever again.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

Pushed to linux-mtd.git, in hopes to submit a pull request for 3.12.

David, I have pushed and signed (with my new key) this and Huang's
regression fix to linux-mtd.git. I can send a pull request, or you can
just drop my tag and do it yourself. I'm not sure how long to wait at
this stage in the release cycle...

Brian


From computersforpeace at gmail.com  Thu Oct 24 18:19:20 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 15:19:20 -0700
Subject: [PATCH v2 fix] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382604496-28118-1-git-send-email-b32955@freescale.com>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382604496-28118-1-git-send-email-b32955@freescale.com>
Message-ID: <20131024221920.GF20061@ld-irv-0074.broadcom.com>

On Thu, Oct 24, 2013 at 04:48:16PM +0800, Huang Shijie wrote:
> The legacy ecc layout is to use all the OOB area by computing the ecc strength
> and ecc step size ourselves.
> 
> The patch "2febcdf mtd: gpmi: set the BCHs geometry with the ecc info"
> makes the gpmi to use the ECC info(ecc strength and ecc step size)
> provided by the MTD code, and creates a different NAND ecc layout
> for the BCH , and use the new ecc layout, this brings a regression to us:
>    We can not mount the ubifs which was created by the old NAND ecc layout.
> 
> This patch fixes this issue by use the legacy ecc layout firstly, if it fails
> we try to use the new ecc layout.
> 
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> Cc: stable at vger.kernel.org

I fixed up the language a little, dropped the 'stable', and pushed to
linux-mtd.git (in hopes of sending another pull request for 3.12). I'll
see if David wants to weigh in first.

Feel free to send your updated DT binding patch(es).

Brian


From marek.belisko at gmail.com  Thu Oct 24 18:24:38 2013
From: marek.belisko at gmail.com (Belisko Marek)
Date: Fri, 25 Oct 2013 00:24:38 +0200
Subject: [PATCH 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <1382652737-20239-5-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382652737-20239-5-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <CAAfyv37SL94Ohwqqs6u5AMvdj4aAgQMGRe_9zze=TcS5An_U0w@mail.gmail.com>

Hi,

On Fri, Oct 25, 2013 at 12:12 AM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> This simplifies the error path and makes the code less error-prone.
>
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/nand/omap2.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index e01a936..d4cafb0 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1837,7 +1837,7 @@ static int omap_nand_probe(struct platform_device *pdev)
>                 return -ENODEV;
>         }
>
> -       info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
> +       info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
>         if (!info)
>                 return -ENOMEM;
>
> @@ -2066,9 +2066,6 @@ out_release_mem_region:
>         if (info->gpmc_irq_fifo > 0)
>                 free_irq(info->gpmc_irq_fifo, info);
>         release_mem_region(info->phys_base, info->mem_size);
> -out_free_info:
You remove ^^^^ statement but it's still used in line ~1868 as return when
cannot get resource.
> -       kfree(info);
> -
>         return err;
>  }
>
> @@ -2091,7 +2088,6 @@ static int omap_nand_remove(struct platform_device *pdev)
>         nand_release(&info->mtd);
>         iounmap(info->nand.IO_ADDR_R);
>         release_mem_region(info->phys_base, info->mem_size);
> -       kfree(info);
>         return 0;
>  }
>
> --
> 1.8.1.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

BR,

marek

-- 
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer

Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
twitter: #opennandra
web: http://open-nandra.com


From computersforpeace at gmail.com  Thu Oct 24 18:43:00 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 24 Oct 2013 15:43:00 -0700
Subject: [PATCH v11 04/10] mtd: nand: omap: use DT specified bus-width
 only for scanning NAND device
In-Reply-To: <20131024212714.GB2520@localhost>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <1382619026-4182-5-git-send-email-pekon@ti.com>
 <20131024212714.GB2520@localhost>
Message-ID: <20131024224300.GG20061@ld-irv-0074.broadcom.com>

On Thu, Oct 24, 2013 at 06:27:15PM -0300, Ezequiel Garcia wrote:
> On Thu, Oct 24, 2013 at 06:20:20PM +0530, Pekon Gupta wrote:
> > This patch:
> > - calls nand_scan_ident() using bus-width as passed by DT
> > - removes double calls to nand_scan_ident(), incase first call fails
> >   then omap_nand_probe just returns error.
> > 
> > Signed-off-by: Pekon Gupta <pekon at ti.com>
> > ---
> >  drivers/mtd/nand/omap2.c | 21 +++++++++------------
> >  1 file changed, 9 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index 5596368..f464321 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> > @@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct platform_device *pdev)
> >  	mtd->name		= dev_name(&pdev->dev);
> >  	mtd->owner		= THIS_MODULE;
> >  	nand_chip		= &info->nand;
> > -	nand_chip->options	= pdata->devsize;
> >  	nand_chip->options	|= NAND_SKIP_BBTSCAN;
> >  #ifdef CONFIG_MTD_NAND_OMAP_BCH
> >  	info->of_node		= pdata->of_node;
> > @@ -1904,6 +1903,15 @@ static int omap_nand_probe(struct platform_device *pdev)
> >  		nand_chip->chip_delay = 50;
> >  	}
> >  
> > +	/* scan NAND device connected to chip controller */
> > +	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;
> 
> Hm.. this only works if the device is listed in nand_flash_ids[] array,
> so that ONFI detection is not used.

But this is no more broken than it used to be, no? I mean, you would
never properly detect an x16 ONFI flash with the old
double-nand_scan_ident() method, right?

> To make ONFI detection work I think you
> need to do as Brian suggested and use NAND_BUSWIDTH_AUTO.

I think that is the correct way forward. But Pekon seems to think that
will require more invasive changes to the GPMC code. But I'm not sure
why.

> (Odd: why is there no current user of that auto-width option?)

Hmm, I could have sworn somebody was using that... I know there was some
pending work on using it for GPIO NAND, but Alexander Shiyan never
followed up on the latest comments. It also seems like the original
author (Matthieu Castet) was working on OMAP support about a year ago,
but things stalled when there wasn't proper mainline support for much of
it:

  http://thread.gmane.org/gmane.linux.ports.arm.omap/88550/focus=44770

Personally, I've only ever used x8 NAND, so I don't have much to go on
here.

> Anyway, I really think we should fix this now and independently
> of the evolution of this ECC DT binding discussion.
> That way you can keep sending a smaller ECC DT binding patchset and
> make reviewers focus on what's really important in each case.

AFAIK, the ECC DT bindings were all approved, and the code looked OK to
my knowledge, except for this single patch. I had recommended either its
total removal or its simplification (i.e., this current patch).

I will be taking a last look and queueing this series up soon, I
believe.

> I have a few fixes (based on your work) and I'll send them now, after
> I complete the tests. We can continue our discussion there.

I'll take a look at those soon.

So am I to understand you have hardware for testing Pekon's work now,
Ezequiel? That will be great if we can have better Reviewed-by/Tested-by
results.

Brian


From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:49:24 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:49:24 -0300
Subject: [PATCH v11 04/10] mtd: nand: omap: use DT specified bus-width
 only for scanning NAND device
In-Reply-To: <20131024224300.GG20061@ld-irv-0074.broadcom.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <1382619026-4182-5-git-send-email-pekon@ti.com>
 <20131024212714.GB2520@localhost>
 <20131024224300.GG20061@ld-irv-0074.broadcom.com>
Message-ID: <20131024224923.GA20462@localhost>

On Thu, Oct 24, 2013 at 03:43:00PM -0700, Brian Norris wrote:
> On Thu, Oct 24, 2013 at 06:27:15PM -0300, Ezequiel Garcia wrote:
> > On Thu, Oct 24, 2013 at 06:20:20PM +0530, Pekon Gupta wrote:
> > > This patch:
> > > - calls nand_scan_ident() using bus-width as passed by DT
> > > - removes double calls to nand_scan_ident(), incase first call fails
> > >   then omap_nand_probe just returns error.
> > > 
> > > Signed-off-by: Pekon Gupta <pekon at ti.com>
> > > ---
> > >  drivers/mtd/nand/omap2.c | 21 +++++++++------------
> > >  1 file changed, 9 insertions(+), 12 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > > index 5596368..f464321 100644
> > > --- a/drivers/mtd/nand/omap2.c
> > > +++ b/drivers/mtd/nand/omap2.c
> > > @@ -1856,7 +1856,6 @@ static int omap_nand_probe(struct platform_device *pdev)
> > >  	mtd->name		= dev_name(&pdev->dev);
> > >  	mtd->owner		= THIS_MODULE;
> > >  	nand_chip		= &info->nand;
> > > -	nand_chip->options	= pdata->devsize;
> > >  	nand_chip->options	|= NAND_SKIP_BBTSCAN;
> > >  #ifdef CONFIG_MTD_NAND_OMAP_BCH
> > >  	info->of_node		= pdata->of_node;
> > > @@ -1904,6 +1903,15 @@ static int omap_nand_probe(struct platform_device *pdev)
> > >  		nand_chip->chip_delay = 50;
> > >  	}
> > >  
> > > +	/* scan NAND device connected to chip controller */
> > > +	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;
> > 
> > Hm.. this only works if the device is listed in nand_flash_ids[] array,
> > so that ONFI detection is not used.
> 
> But this is no more broken than it used to be, no? I mean, you would
> never properly detect an x16 ONFI flash with the old
> double-nand_scan_ident() method, right?
> 

That's right. But the issue is not really fixed either.

> > To make ONFI detection work I think you
> > need to do as Brian suggested and use NAND_BUSWIDTH_AUTO.
> 
> I think that is the correct way forward. But Pekon seems to think that
> will require more invasive changes to the GPMC code. But I'm not sure
> why.
> 

Hm... not sure. AFAIK, the GPMC should be *already* configured prior to the
NAND driver being probed.

> > (Odd: why is there no current user of that auto-width option?)
> 
> Hmm, I could have sworn somebody was using that... I know there was some
> pending work on using it for GPIO NAND, but Alexander Shiyan never
> followed up on the latest comments. It also seems like the original
> author (Matthieu Castet) was working on OMAP support about a year ago,
> but things stalled when there wasn't proper mainline support for much of
> it:
> 
>   http://thread.gmane.org/gmane.linux.ports.arm.omap/88550/focus=44770
> 
> Personally, I've only ever used x8 NAND, so I don't have much to go on
> here.
> 
> > Anyway, I really think we should fix this now and independently
> > of the evolution of this ECC DT binding discussion.
> > That way you can keep sending a smaller ECC DT binding patchset and
> > make reviewers focus on what's really important in each case.
> 
> AFAIK, the ECC DT bindings were all approved, and the code looked OK to
> my knowledge, except for this single patch. I had recommended either its
> total removal or its simplification (i.e., this current patch).
> 

FWIW, I'm in favor of *completely* dropping whatever doesn't belong
to the ECC DT binding.

> I will be taking a last look and queueing this series up soon, I
> believe.
> 
> > I have a few fixes (based on your work) and I'll send them now, after
> > I complete the tests. We can continue our discussion there.
> 
> I'll take a look at those soon.
> 

Ok, cool.

> So am I to understand you have hardware for testing Pekon's work now,
> Ezequiel? That will be great if we can have better Reviewed-by/Tested-by
> results.
> 

Yup, I gave it quick test actually, but nothing deep. Let me test some
more maybe later today/tomorrow. I just wanted to sort this out first.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Thu Oct 24 18:50:50 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 24 Oct 2013 19:50:50 -0300
Subject: [PATCH 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <CAAfyv37SL94Ohwqqs6u5AMvdj4aAgQMGRe_9zze=TcS5An_U0w@mail.gmail.com>
References: <1382652737-20239-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382652737-20239-5-git-send-email-ezequiel.garcia@free-electrons.com>
 <CAAfyv37SL94Ohwqqs6u5AMvdj4aAgQMGRe_9zze=TcS5An_U0w@mail.gmail.com>
Message-ID: <20131024225049.GB20462@localhost>

On Fri, Oct 25, 2013 at 12:24:38AM +0200, Belisko Marek wrote:
> Hi,
> 
> On Fri, Oct 25, 2013 at 12:12 AM, Ezequiel Garcia
> <ezequiel.garcia at free-electrons.com> wrote:
> > This simplifies the error path and makes the code less error-prone.
> >
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/nand/omap2.c | 6 +-----
> >  1 file changed, 1 insertion(+), 5 deletions(-)
> >
> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index e01a936..d4cafb0 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> > @@ -1837,7 +1837,7 @@ static int omap_nand_probe(struct platform_device *pdev)
> >                 return -ENODEV;
> >         }
> >
> > -       info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
> > +       info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> >         if (!info)
> >                 return -ENOMEM;
> >
> > @@ -2066,9 +2066,6 @@ out_release_mem_region:
> >         if (info->gpmc_irq_fifo > 0)
> >                 free_irq(info->gpmc_irq_fifo, info);
> >         release_mem_region(info->phys_base, info->mem_size);
> > -out_free_info:
> You remove ^^^^ statement but it's still used in line ~1868 as return when
> cannot get resource.

Right, I missed that. This happens when you do two cleanups at once and then
try to commit them separatedly!

Thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From grant.likely at linaro.org  Thu Oct 24 20:15:09 2013
From: grant.likely at linaro.org (Grant Likely)
Date: Fri, 25 Oct 2013 01:15:09 +0100
Subject: [PATCH 5/5] mtd: m25p80: remove 'disabled' device check
In-Reply-To: <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131025001509.1924FC403B6@trevor.secretlab.ca>

On Wed, 23 Oct 2013 19:58:23 -0700, Brian Norris <computersforpeace at gmail.com> wrote:
> It seems like the following commit was never necessary
> 
>     commit 5f949137952020214cd167093dd7be448f21c079
>     Author: Shaohui Xie <Shaohui.Xie at freescale.com>
>     Date:   Fri Oct 14 15:49:00 2011 +0800
> 
>         mtd: m25p80: don't probe device which has status of 'disabled'
> 
> because it duplicates the code in of_platform_device_create_pdata()
> which ensures that 'disabled' nodes are never instantiated.
> 
> Also, drop the __maybe_unused.

Looks reasonable.

Reviewed-by: Grant Likely <grant.likely at linaro.org>

> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Cc: Grant Likely <grant.likely at linaro.org>
> Cc: Rob Herring <rob.herring at calxeda.com>
> Cc: <devicetree at vger.kernel.org>
> ---
>  drivers/mtd/devices/m25p80.c | 7 +------
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index d6c5c57..a1dc49a 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -935,12 +935,7 @@ static int m25p_probe(struct spi_device *spi)
>  	struct flash_info		*info;
>  	unsigned			i;
>  	struct mtd_part_parser_data	ppdata;
> -	struct device_node __maybe_unused *np = spi->dev.of_node;
> -
> -#ifdef CONFIG_MTD_OF_PARTS
> -	if (!of_device_is_available(np))
> -		return -ENODEV;
> -#endif
> +	struct device_node *np = spi->dev.of_node;
>  
>  	/* Platform data helps sort out which chip type we have, as
>  	 * well as how this board partitions it.  If we don't have
> -- 
> 1.8.4
> 



From b32955 at freescale.com  Fri Oct 25 04:36:24 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Fri, 25 Oct 2013 16:36:24 +0800
Subject: [PATCH] mtd: gpmi: add a new DT property to use the datasheet's
 minimum required ECC
Message-ID: <1382690184-27124-1-git-send-email-b32955@freescale.com>

In default way, we use the ecc-strength/ecc-step-size calculated by ourselves
and use all the OOB area.

This patch adds a new property : "fsl,use-minimum-ecc"

If we enable it, we will use the datasheet's minimum required ECC provided by
the MTD layer (the ecc_strength_ds/ecc_strength_ds fields in the nand_chip{}).
So we may have free space in the OOB area by using the minimum ECC, and we may
support JFFS2 with some SLC NANDs, such as Micron's SLC NAND.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
 .../devicetree/bindings/mtd/gpmi-nand.txt          |    6 ++++++
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c             |    4 ++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index 551b2a1..7a5afa8 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -17,6 +17,12 @@ Required properties:
 Optional properties:
   - nand-on-flash-bbt: boolean to enable on flash bbt option if not
                        present false
+  - fsl,use-minimum-ecc: By enabling this boolean property, the gpmi will try
+                       to use the datasheet's minimum required ECC provided by
+                       the MTD layer (the ecc_strength_ds/ecc_strength_ds fields
+                       in the nand_chip{}). So we may have free space in the OOB
+                       area by using the minimum ECC, and we may support JFFS2
+                       with some SLC NANDs, such as Micron's SLC NAND.
 
 The device tree may optionally contain sub-nodes describing partitions of the
 address space. See partition.txt for more detail.
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 43a62e8..d0ae7f4 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -352,6 +352,10 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
+	if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
+		return set_geometry_by_ecc_info(this) ? 0 :
+						legacy_set_geometry(this);
+
 	return legacy_set_geometry(this) ?
 		(!set_geometry_by_ecc_info(this)) : 0;
 }
-- 
1.7.2.rc3




From sourav.poddar at ti.com  Fri Oct 25 05:25:45 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 25 Oct 2013 14:55:45 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
Message-ID: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>

Some flash also support quad read mode.
Adding support for adding quad mode in m25p80
for spansion and macronix flash.

Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
---
This posted was initially posted as a series[1],
posting this as a seperate feature patch, while other
patch in that series will go as a seperate feature patch.

Brian,
 I have rebased this patches on top of l2-mtd + 
 http://permalink.gmane.org/gmane.linux.drivers.mtd/49129

Changes from the previous version [1]
- Added deault 4 byte command.
- Make the code more modular by using
  different apis "set_quad_mode" etc.
- Remove few bug fixes which went as a seperate patch
  from Brian's series.
- Miscellaneous cleanups.
- Change the subject to reflect m25p80 changes.
[1]: http://permalink.gmane.org/gmane.linux.drivers.mtd/48755

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

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d6c5c57..88f9421 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -41,6 +41,7 @@
 #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
 #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ        0x6b    /* Read data bytes */
 #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
 #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
 #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
@@ -48,10 +49,12 @@
 #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
+#define	OPCODE_RDCR             0x35    /* Read configuration register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ_4B	0x6c    /* Read data bytes */
 #define	OPCODE_PP_4B		0x12	/* Page program (up to 256 bytes) */
 #define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
 
@@ -76,6 +79,10 @@
 #define	SR_BP2			0x10	/* Block protect 2 */
 #define	SR_SRWD			0x80	/* SR write protect */
 
+/* Configuration Register bits. */
+#define CR_QUAD_EN_SPAN		0x2     /* Spansion Quad I/O */
+#define SR_QUAD_EN_MX		0x40    /* Macronix Quad I/O */
+
 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
 #define	MAX_CMD_SIZE		6
@@ -95,6 +102,7 @@ struct m25p {
 	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
+	bool                    quad_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -131,6 +139,26 @@ static int read_sr(struct m25p *flash)
 }
 
 /*
+ * Read configuration register, returning its value in the
+ * location. Return the configuration register value.
+ * Returns negative if error occured.
+ */
+static int read_cr(struct m25p *flash)
+{
+	u8 code = OPCODE_RDCR;
+	int ret;
+	u8 val;
+
+	ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
@@ -220,6 +248,95 @@ static int wait_till_ready(struct m25p *flash)
 }
 
 /*
+ * Write status Register and configuration register with 2 bytes
+ * The first byte will be written to the status register, while the
+ * second byte will be written to the configuration register.
+ * Return negative if error occured.
+ */
+static int write_sr_cr(struct m25p *flash, u16 val)
+{
+	flash->command[0] = OPCODE_WRSR;
+	flash->command[1] = val & 0xff;
+	flash->command[2] = (val >> 8);
+
+	return spi_write(flash->spi, flash->command, 3);
+}
+
+static int macronix_quad_enable(struct m25p *flash)
+{
+	int ret, val;
+	u8 cmd[2];
+	cmd[0] = OPCODE_WRSR;
+
+	val = read_sr(flash);
+	cmd[1] = val | SR_QUAD_EN_MX;
+	write_enable(flash);
+
+	spi_write(flash->spi, &cmd, 2);
+
+	if (wait_till_ready(flash))
+		return 1;
+
+	ret = read_sr(flash);
+	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+		dev_err(&flash->spi->dev,
+			"Macronix Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int spansion_quad_enable(struct m25p *flash)
+{
+	int ret;
+	int quad_en = CR_QUAD_EN_SPAN << 8;
+
+	write_enable(flash);
+
+	ret = write_sr_cr(flash, quad_en);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev,
+			"error while writing configuration register");
+		return -EINVAL;
+	}
+
+	/* read back and check it */
+	ret = read_cr(flash);
+	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+		dev_err(&flash->spi->dev,
+			"Spansion Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline int set_quad_mode(struct m25p *flash, u32 jedec_id)
+{
+	int status;
+
+	switch (JEDEC_MFR(jedec_id)) {
+	case CFI_MFR_MACRONIX:
+		status = macronix_quad_enable(flash);
+		if (status) {
+			dev_err(&flash->spi->dev,
+				"Macronix quad not enable");
+			return -EINVAL;
+		}
+		return status;
+	default:
+		status = spansion_quad_enable(flash);
+		if (status) {
+			dev_err(&flash->spi->dev,
+				"Spansion quad not enable");
+			return -EINVAL;
+		}
+		return status;
+	}
+}
+
+/*
  * Erase the whole flash memory
  *
  * Returns 0 if successful, non-zero otherwise.
@@ -253,11 +370,24 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
 	cmd[4] = addr >> (flash->addr_width * 8 - 32);
 }
 
+/*
+ * Dummy Cycle calculation for fast and quad read.
+ * It can be used to support more commands with
+ * different dummy cycle requirement.
+ */
 static int m25p_cmdsz(struct m25p *flash)
 {
 	return 1 + flash->addr_width;
 }
 
+static inline int m25p80_dummy_cycles_read(struct m25p *flash)
+{
+	if (flash->quad_read || flash->fast_read)
+		return 1;
+
+	return 0;
+}
+
 /*
  * Erase one sector of flash memory at offset ``offset'' which is any
  * address within the sector which should be erased.
@@ -368,9 +498,10 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	memset(t, 0, (sizeof t));
 
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
+	t[0].len = m25p_cmdsz(flash) + m25p80_dummy_cycles_read(flash);
 	spi_message_add_tail(&t[0], &m);
 
+	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;
 	t[1].rx_buf = buf;
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
@@ -392,7 +523,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	spi_sync(flash->spi, &m);
 
 	*retlen = m.actual_length - m25p_cmdsz(flash) -
-			(flash->fast_read ? 1 : 0);
+			m25p80_dummy_cycles_read(flash);
 
 	mutex_unlock(&flash->lock);
 
@@ -698,6 +829,7 @@ struct flash_info {
 #define	SST_WRITE	0x04		/* use SST byte programming */
 #define	M25P_NO_FR	0x08		/* Can't do fastread */
 #define	SECT_4K_PMC	0x10		/* OPCODE_BE_4K_PMC works uniformly */
+#define	M25P80_QUAD_READ	0x20    /* Flash supports Quad Read */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
 
 	/* Micron */
 	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
@@ -794,7 +926,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
 	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, M25P80_QUAD_READ) },
 	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -936,6 +1068,7 @@ static int m25p_probe(struct spi_device *spi)
 	unsigned			i;
 	struct mtd_part_parser_data	ppdata;
 	struct device_node __maybe_unused *np = spi->dev.of_node;
+	int ret;
 
 #ifdef CONFIG_MTD_OF_PARTS
 	if (!of_device_is_available(np))
@@ -1055,6 +1188,15 @@ static int m25p_probe(struct spi_device *spi)
 	flash->page_size = info->page_size;
 	flash->mtd.writebufsize = flash->page_size;
 
+	if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
+		ret = set_quad_mode(flash, info->jedec_id);
+		if (ret) {
+			dev_err(&flash->spi->dev, "quad mode not supported\n");
+			return ret;
+		}
+		flash->quad_read = true;
+	}
+
 	if (np)
 		/* If we were instantiated by DT, use it */
 		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
@@ -1067,7 +1209,9 @@ static int m25p_probe(struct spi_device *spi)
 		flash->fast_read = false;
 
 	/* Default commands */
-	if (flash->fast_read)
+	if (flash->quad_read)
+		flash->read_opcode = OPCODE_QUAD_READ;
+	else if (flash->fast_read)
 		flash->read_opcode = OPCODE_FAST_READ;
 	else
 		flash->read_opcode = OPCODE_NORM_READ;
@@ -1081,6 +1225,12 @@ static int m25p_probe(struct spi_device *spi)
 		flash->addr_width = 4;
 		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
 			/* Dedicated 4-byte command set */
+			if (flash->quad_read)
+				flash->read_opcode = OPCODE_QUAD_READ_4B;
+			else
+				flash->read_opcode = flash->fast_read ?
+					OPCODE_FAST_READ_4B :
+					OPCODE_NORM_READ_4B;
 			flash->read_opcode = flash->fast_read ?
 				OPCODE_FAST_READ_4B :
 				OPCODE_NORM_READ_4B;
-- 
1.7.1



From b32955 at freescale.com  Fri Oct 25 06:18:43 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Fri, 25 Oct 2013 18:18:43 +0800
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <526A4583.9050008@freescale.com>

? 2013?10?25? 17:25, Sourav Poddar ??:
>   I have rebased this patches on top of l2-mtd +
>   http://permalink.gmane.org/gmane.linux.drivers.mtd/49129
>
Why i can not git-am this patch with the latest l2-mtd?

Huang Shijie



From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:17:55 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:17:55 -0300
Subject: [PATCH v2 3/5] mtd: nand: omap2: Fix OMAP_BCH option dependency
In-Reply-To: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382696277-9063-4-git-send-email-ezequiel.garcia@free-electrons.com>

This option does not need to depend in MTD_NAND, for it's enclosed
under it. Also, it's wrong to make it depend in ARCH_OMAP3 only
since the controller is used in a wider range of SoCs.

Instead, just leave the dependency on the OMAP2 driver option.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..8187466 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
 	  platforms.
 
 config MTD_NAND_OMAP_BCH
-	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
+	depends on MTD_NAND_OMAP2
 	tristate "Enable support for hardware BCH error correction"
 	default n
 	select BCH
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:17:56 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:17:56 -0300
Subject: [PATCH v2 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382696277-9063-5-git-send-email-ezequiel.garcia@free-electrons.com>

This simplifies the error path and makes the code less error-prone.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index e01a936..d3155b2 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1837,7 +1837,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return -ENOMEM;
 
@@ -2067,8 +2067,6 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_fifo, info);
 	release_mem_region(info->phys_base, info->mem_size);
 out_free_info:
-	kfree(info);
-
 	return err;
 }
 
@@ -2091,7 +2089,6 @@ static int omap_nand_remove(struct platform_device *pdev)
 	nand_release(&info->mtd);
 	iounmap(info->nand.IO_ADDR_R);
 	release_mem_region(info->phys_base, info->mem_size);
-	kfree(info);
 	return 0;
 }
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:17:54 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:17:54 -0300
Subject: [PATCH v2 2/5] mtd: nand: omap2: Fix device detection path
In-Reply-To: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382696277-9063-3-git-send-email-ezequiel.garcia@free-electrons.com>

From: Pekon Gupta <pekon at ti.com>

Because the device bus can be 8-bit or 16-bit width, yet ONFI detection
cannot work in 16-bit mode, we need to set the NAND_BUSWIDTH_AUTO option
which allows proper initialization configuration.

Once the bus width is detected, nand_scan_ident() updates the nand_chip struct
'option' field to use the appropriate read/write functions and configure
the ECC engine.

Signed-off-by: Pekon Gupta <pekon at ti.com>
[rebased and clean-up a bit pekon's original work]
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 4ecf0e5..e01a936 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1855,8 +1855,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->mtd.name		= dev_name(&pdev->dev);
 	info->mtd.owner		= THIS_MODULE;
 
-	info->nand.options	= pdata->devsize;
-	info->nand.options	|= NAND_SKIP_BBTSCAN;
+	info->nand.options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 #ifdef CONFIG_MTD_NAND_OMAP_BCH
 	info->of_node		= pdata->of_node;
 #endif
@@ -1903,6 +1902,10 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->nand.chip_delay = 50;
 	}
 
+	err = nand_scan_ident(&info->mtd, 1, NULL);
+	if (err < 0)
+		goto out_release_mem_region;
+
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		info->nand.read_buf   = omap_read_buf_pref;
@@ -2013,17 +2016,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 		}
 	}
 
-	/* DIP switches on some boards change between 8 and 16 bit
-	 * bus widths for flash.  Try the other width if the first try fails.
-	 */
-	if (nand_scan_ident(&info->mtd, 1, NULL)) {
-		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan_ident(&info->mtd, 1, NULL)) {
-			err = -ENXIO;
-			goto out_release_mem_region;
-		}
-	}
-
 	/* rom code layout */
 	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:17:53 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:17:53 -0300
Subject: [PATCH v2 1/5] ARM: am335x-bone: Add support for 16-bit NAND cape
In-Reply-To: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382696277-9063-2-git-send-email-ezequiel.garcia@free-electrons.com>

From: Pekon Gupta <pekon at ti.com>

Add GPMC timing configurations and NAND partitions for the Beaglebone
"NAND cape". Further information and datasheets of this cape can be found at:
- http://beagleboardtoys.info/index.php?title=BeagleBone_Memory_Expansion
- http://beagleboardtoys.info/index.php?title=BeagleBone_4Gb_16-Bit_NAND_Module

Signed-off-by: Pekon Gupta <pekon at ti.com>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
This patch is not really intended for inclusion. I'm just adding it
to the series for reference and in case anyone wants to test.

In particular, this patch includes two different GPMC configurations:
one at am335x-bone-common.dtsi, and another one at am335x-boneblack.dts,
overriding the first one. The former is Pekon's, while the latter is mine,
to support the flash device on my setup.

 arch/arm/boot/dts/am335x-bone-common.dtsi | 28 ++++++++++++
 arch/arm/boot/dts/am335x-bone.dts         | 75 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/am335x-boneblack.dts    | 69 ++++++++++++++++++++++++++++
 3 files changed, 172 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi
index 2f66ded..73dcc58 100644
--- a/arch/arm/boot/dts/am335x-bone-common.dtsi
+++ b/arch/arm/boot/dts/am335x-bone-common.dtsi
@@ -107,6 +107,34 @@
 				0x14c (PIN_INPUT_PULLDOWN | MUX_MODE7)
 			>;
 		};
+
+		nandflash_pins_s0: nandflash_pins_s0 {
+			pinctrl-single,pins = <
+				0x0 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad0.gpmc_ad0 */
+				0x4 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad1.gpmc_ad1 */
+				0x8 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad2.gpmc_ad2 */
+				0xc (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad3.gpmc_ad3 */
+				0x10 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad4.gpmc_ad4 */
+				0x14 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad5.gpmc_ad5 */
+				0x18 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad6.gpmc_ad6 */
+				0x1c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad7.gpmc_ad7 */
+				0x20 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad8.gpmc_ad8 */
+				0x24 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad9.gpmc_ad9 */
+				0x28 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad10.gpmc_ad10 */
+				0x2c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad11.gpmc_ad11 */
+				0x30 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad12.gpmc_ad12 */
+				0x34 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad13.gpmc_ad13 */
+				0x38 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad14.gpmc_ad14 */
+				0x3c (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_ad15.gpmc_ad15 */
+				0x70 (PIN_INPUT_PULLUP | MUX_MODE0)	/* gpmc_wait0.gpmc_wait0 */
+				0x74 (PIN_INPUT_PULLUP | MUX_MODE7)	/* gpmc_wpn.gpio0_30 */
+				0x7c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_csn0.gpmc_csn0  */
+				0x90 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_advn_ale.gpmc_advn_ale */
+				0x94 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_oen_ren.gpmc_oen_ren */
+				0x98 (PIN_OUTPUT | MUX_MODE0)		/* gpmc_wen.gpmc_wen */
+				0x9c (PIN_OUTPUT | MUX_MODE0)		/* gpmc_be0n_cle.gpmc_be0n_cle */
+			>;
+		};
 	};
 
 	ocp {
diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts
index 7993c48..d9172c7 100644
--- a/arch/arm/boot/dts/am335x-bone.dts
+++ b/arch/arm/boot/dts/am335x-bone.dts
@@ -9,3 +9,78 @@
 
 #include "am33xx.dtsi"
 #include "am335x-bone-common.dtsi"
+
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	nand at 0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+		gpmc,device-width = <2>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <740>;
+		gpmc,cs-wr-off-ns = <740>;
+		gpmc,adv-on-ns = <0>;
+		gpmc,adv-rd-off-ns = <740>;
+		gpmc,adv-wr-off-ns = <740>;
+		gpmc,we-on-ns = <90>;
+		gpmc,we-off-ns = <600>;
+		gpmc,oe-on-ns = <150>;
+		gpmc,oe-off-ns = <650>;
+		gpmc,access-ns = <560>;
+		gpmc,rd-cycle-ns = <740>;
+		gpmc,wr-cycle-ns = <740>;
+		gpmc,wait-on-read = "true";
+		gpmc,wait-on-write = "true";
+		gpmc,bus-turnaround-ns = <0>;
+		gpmc,cycle2cycle-delay-ns = <0>;
+		gpmc,clk-activation-ns = <0>;
+		gpmc,wait-monitoring-ns = <0>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ti,elm-id = <&elm>;
+		/* MTD partition table */
+		partition at 0 {
+			label = "SPL1";
+			reg = <0x00000000 0x000020000>;
+		};
+		partition at 1 {
+			label = "SPL2";
+			reg = <0x00020000 0x00020000>;
+		};
+		partition at 2 {
+			label = "SPL3";
+			reg = <0x00040000 0x00020000>;
+		};
+		partition at 3 {
+			label = "SPL4";
+			reg = <0x00060000 0x00020000>;
+		};
+		partition at 4 {
+			label = "U-boot";
+			reg = <0x00080000 0x001e0000>;
+		};
+		partition at 5 {
+			label = "environment";
+			reg = <0x00260000 0x00020000>;
+		};
+		partition at 6 {
+			label = "Kernel";
+			reg = <0x00280000 0x00500000>;
+		};
+		partition at 7 {
+			label = "File-System";
+			reg = <0x00780000 0x0F880000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts
index 197cadf..e30f58a 100644
--- a/arch/arm/boot/dts/am335x-boneblack.dts
+++ b/arch/arm/boot/dts/am335x-boneblack.dts
@@ -15,3 +15,72 @@
 	regulator-max-microvolt = <1800000>;
 	regulator-always-on;
 };
+
+&elm {
+	status = "okay";
+};
+
+&gpmc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nandflash_pins_s0>;
+	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
+	nand at 0,0 {
+		reg = <0 0 0>; /* CS0, offset 0 */
+		nand-bus-width = <16>;
+		ti,nand-ecc-opt = "bch8";
+
+		gpmc,device-width = <2>;
+		gpmc,sync-clk-ps = <0>;
+		gpmc,cs-on-ns = <0>;
+		gpmc,cs-rd-off-ns = <44>;
+		gpmc,cs-wr-off-ns = <44>;
+		gpmc,adv-on-ns = <6>;
+		gpmc,adv-rd-off-ns = <34>;
+		gpmc,adv-wr-off-ns = <44>;
+		gpmc,we-off-ns = <40>;
+		gpmc,oe-off-ns = <54>;
+		gpmc,access-ns = <64>;
+		gpmc,rd-cycle-ns = <82>;
+		gpmc,wr-cycle-ns = <82>;
+		gpmc,wr-access-ns = <40>;
+		gpmc,wr-data-mux-bus-ns = <0>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ti,elm-id = <&elm>;
+		/* MTD partition table */
+		partition at 0 {
+			label = "SPL1";
+			reg = <0x00000000 0x000020000>;
+		};
+		partition at 1 {
+			label = "SPL2";
+			reg = <0x00020000 0x00020000>;
+		};
+		partition at 2 {
+			label = "SPL3";
+			reg = <0x00040000 0x00020000>;
+		};
+		partition at 3 {
+			label = "SPL4";
+			reg = <0x00060000 0x00020000>;
+		};
+		partition at 4 {
+			label = "U-boot";
+			reg = <0x00080000 0x001e0000>;
+		};
+		partition at 5 {
+			label = "environment";
+			reg = <0x00260000 0x00020000>;
+		};
+		partition at 6 {
+			label = "Kernel";
+			reg = <0x00280000 0x00500000>;
+		};
+		partition at 7 {
+			label = "File-System";
+			reg = <0x00780000 0x0F880000>;
+		};
+	};
+};
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:17:57 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:17:57 -0300
Subject: [PATCH v2 5/5] mtd: nand: omap2: Use devm_ioremap_resource
In-Reply-To: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382696277-9063-6-git-send-email-ezequiel.garcia@free-electrons.com>

This simplifies the code and makes it less error-prone. In fact,
this commit fixes a missing iounmap() in the cleanup error path.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 31 +++++++------------------------
 1 file changed, 7 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index d3155b2..2d896da 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1830,6 +1830,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	unsigned sig;
 	struct resource			*res;
 	struct mtd_part_parser_data	ppdata = {};
+	void __iomem			*base;
 
 	pdata = dev_get_platdata(&pdev->dev);
 	if (pdata == NULL) {
@@ -1861,29 +1862,15 @@ static int omap_nand_probe(struct platform_device *pdev)
 #endif
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		err = -EINVAL;
-		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto out_free_info;
-	}
-
-	info->phys_base = res->start;
-	info->mem_size = resource_size(res);
-
-	if (!request_mem_region(info->phys_base, info->mem_size,
-				pdev->dev.driver->name)) {
-		err = -EBUSY;
-		goto out_free_info;
-	}
-
-	info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size);
-	if (!info->nand.IO_ADDR_R) {
-		err = -ENOMEM;
-		goto out_release_mem_region;
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base)) {
+		err = PTR_ERR(base);
+		return err;
 	}
 
 	info->nand.controller = &info->controller;
 
+	info->nand.IO_ADDR_R = base;
 	info->nand.IO_ADDR_W = info->nand.IO_ADDR_R;
 	info->nand.cmd_ctrl  = omap_hwcontrol;
 
@@ -1904,7 +1891,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	err = nand_scan_ident(&info->mtd, 1, NULL);
 	if (err < 0)
-		goto out_release_mem_region;
+		return err;
 
 	switch (pdata->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
@@ -2065,8 +2052,6 @@ out_release_mem_region:
 		free_irq(info->gpmc_irq_count, info);
 	if (info->gpmc_irq_fifo > 0)
 		free_irq(info->gpmc_irq_fifo, info);
-	release_mem_region(info->phys_base, info->mem_size);
-out_free_info:
 	return err;
 }
 
@@ -2087,8 +2072,6 @@ 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, info->mem_size);
 	return 0;
 }
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:17:52 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:17:52 -0300
Subject: [PATCH v2 0/5] Assorted OMAP2 NAND clean-ups
Message-ID: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>

Hello everyone,

As it was discussed recently in the mailing list, the omap2-nand driver currently
has an issue preventing proper ONFI detection of 16-bit devices (other drivers
may suffer from this same issue).

In an attempt to address such issue, patch 2/5 "mtd: nand: omap2: Fix device
detection path" uses NAND_BUSWIDTH_AUTO (actually discarding any DT property)
and leaves the bus width detection the NAND core code.

I've based the patch in previously sent work by Pekon Gupta, did some work and
added my name on it. I hope it's fine to handle the authorship like this.
Otherwise, feel free to tell.

This has been tested in a Beaglebone black (AM335x) board with a 16-bit Micron
NAND device, both ONFI and array-based detections work fine:

[    1.253200] omap-gpmc 50000000.gpmc: GPMC revision 6.0
[    1.260638] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron MT29F4G16ABADAH4)
[    1.269110] NAND device: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.275721] Missing elm_id property, fall back to Software BCH
[    1.283546] enabling NAND BCH ecc with 8-bit correction
[    1.290219] 8 ofpart partitions found on MTD device omap2-nand.0
[    1.296591] Creating 8 MTD partitions on "omap2-nand.0":
[    1.302192] 0x000000000000-0x000000020000 : "SPL1"
[    1.309884] 0x000000020000-0x000000040000 : "SPL2"
[    1.316332] 0x000000040000-0x000000060000 : "SPL3"
[    1.322599] 0x000000060000-0x000000080000 : "SPL4"
[    1.328877] 0x000000080000-0x000000260000 : "U-boot"
[    1.336763] 0x000000260000-0x000000280000 : "environment"
[    1.343575] 0x000000280000-0x000000780000 : "Kernel"
[    1.354074] 0x000000780000-0x000010000000 : "File-System"

Also, a quick run of nandtest ends successfully:

$ nandtest /dev/mtd7
ECC corrections: 0
ECC failures   : 0
Bad blocks     : 2
BBT blocks     : 0
Bad block at 0x00000000
Bad block at 0x00520000
[...]
Finished pass 1 successfully

The first patch 1/5 is included just for reference of the DT GPMC configuration
currently in use, together with required pinmuxing, in case anyone feels like
testing. It's not intended to be merged, since it doesn't belong to the Beaglebone
board itself, but instead it's an attached daughter board.

The other patches are just minor cleanups I came across while looking at the code.
As usual, the patchset applies on top of latest l2-mtd's master branch.

Pekon, Brian: Do you think this solution might work for 8-bit and 16-bit devices?

I've been going through the GPMC code again, and it looks like some cleaning is needed
there two, but that's a different story!

Feel free to comment or provide any feedback!

Changes from v1:

  * As noticed by Belisko Marek, re-added the out_free_info label
    in PATCH 4/5 to prevent build failures. The result is the same
    and the label is removed in the last patch, together with the last
    users of it.

Ezequiel Garcia (3):
  mtd: nand: omap2: Fix OMAP_BCH option dependency
  mtd: nand: omap2: Use devm_kzalloc
  mtd: nand: omap2: Use devm_ioremap_resource

Pekon Gupta (2):
  ARM: am335x-bone: Add support for 16-bit NAND cape
  mtd: nand: omap2: Fix device detection path

 arch/arm/boot/dts/am335x-bone-common.dtsi | 28 ++++++++++++
 arch/arm/boot/dts/am335x-bone.dts         | 75 +++++++++++++++++++++++++++++++
 arch/arm/boot/dts/am335x-boneblack.dts    | 69 ++++++++++++++++++++++++++++
 drivers/mtd/nand/Kconfig                  |  2 +-
 drivers/mtd/nand/omap2.c                  | 52 +++++----------------
 5 files changed, 185 insertions(+), 41 deletions(-)

-- 
1.8.1.5



From sourav.poddar at ti.com  Fri Oct 25 06:19:00 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Fri, 25 Oct 2013 15:49:00 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526A4583.9050008@freescale.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <526A4583.9050008@freescale.com>
Message-ID: <526A4594.1050403@ti.com>

On Friday 25 October 2013 03:48 PM, Huang Shijie wrote:
> ? 2013?10?25? 17:25, Sourav Poddar ??:
>>   I have rebased this patches on top of l2-mtd +
>>   http://permalink.gmane.org/gmane.linux.drivers.mtd/49129
>>
> Why i can not git-am this patch with the latest l2-mtd?
>
May be some format issue, better to save it from mail and apply.
> Huang Shijie
>



From pekon at ti.com  Fri Oct 25 06:25:02 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 25 Oct 2013 10:25:02 +0000
Subject: [PATCH v2 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <1382696277-9063-5-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382696277-9063-5-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2AD60@DBDE04.ent.ti.com>

Hi,

> 
> This simplifies the error path and makes the code less error-prone.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/nand/omap2.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index e01a936..d3155b2 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1837,7 +1837,7 @@ static int omap_nand_probe(struct
> platform_device *pdev)
>  		return -ENODEV;
>  	}
> 
> -	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
> +	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
>  	if (!info)
>  		return -ENOMEM;
> 
> @@ -2067,8 +2067,6 @@ out_release_mem_region:
>  		free_irq(info->gpmc_irq_fifo, info);
>  	release_mem_region(info->phys_base, info->mem_size);
>  out_free_info:
> -	kfree(info);
> -
>  	return err;
>  }
> 
> @@ -2091,7 +2089,6 @@ static int omap_nand_remove(struct
> platform_device *pdev)
>  	nand_release(&info->mtd);
>  	iounmap(info->nand.IO_ADDR_R);
>  	release_mem_region(info->phys_base, info->mem_size);
> -	kfree(info);
>  	return 0;
>  }
> 
> --
> 1.8.1.5

I think these changes are already done as part of following patch..
http://lists.infradead.org/pipermail/linux-mtd/2013-October/049418.html

Did your rebase on my patch-set ?


with regards, pekon


From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:42:47 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:42:47 -0300
Subject: [PATCH v2 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2AD60@DBDE04.ent.ti.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382696277-9063-5-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AD60@DBDE04.ent.ti.com>
Message-ID: <20131025104246.GA2489@localhost>

On Fri, Oct 25, 2013 at 10:25:02AM +0000, Gupta, Pekon wrote:
> Hi,
> 
> > 
> > This simplifies the error path and makes the code less error-prone.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/nand/omap2.c | 5 +----
> >  1 file changed, 1 insertion(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> > index e01a936..d3155b2 100644
> > --- a/drivers/mtd/nand/omap2.c
> > +++ b/drivers/mtd/nand/omap2.c
> > @@ -1837,7 +1837,7 @@ static int omap_nand_probe(struct
> > platform_device *pdev)
> >  		return -ENODEV;
> >  	}
> > 
> > -	info = kzalloc(sizeof(struct omap_nand_info), GFP_KERNEL);
> > +	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
> >  	if (!info)
> >  		return -ENOMEM;
> > 
> > @@ -2067,8 +2067,6 @@ out_release_mem_region:
> >  		free_irq(info->gpmc_irq_fifo, info);
> >  	release_mem_region(info->phys_base, info->mem_size);
> >  out_free_info:
> > -	kfree(info);
> > -
> >  	return err;
> >  }
> > 
> > @@ -2091,7 +2089,6 @@ static int omap_nand_remove(struct
> > platform_device *pdev)
> >  	nand_release(&info->mtd);
> >  	iounmap(info->nand.IO_ADDR_R);
> >  	release_mem_region(info->phys_base, info->mem_size);
> > -	kfree(info);
> >  	return 0;
> >  }
> > 
> > --
> > 1.8.1.5
> 
> I think these changes are already done as part of following patch..
> http://lists.infradead.org/pipermail/linux-mtd/2013-October/049418.html
> 
> Did your rebase on my patch-set ?
> 

Hm.. well the problem with that patch is that it's in the middle of an
unrelated series. As I already told you, I think you should have pushed
that as a one-patch fix. Have you seen that suggestion?

On the other side, you're fixing too many things in that single patch,
for my taste. Maybe I'm not the smarter developer, but going through
that patch is not easy to catch if there's no mistake done.

Usually if it's possible to split a patch (maintaining consistency) it makes
the reviewing process easier.
If you'd rather send this devm_xxx change yourself that's fine by me,
but *please* split the patch in two and write proper commit messages.

Anyway: this is just a silly change, the important one is the other
nand_scan_ident() fix. Could you help me review that?

I'm interested in knowing how will that work with 8-bit and 16-bit devices.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Fri Oct 25 06:56:27 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 07:56:27 -0300
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up of
 supported ECC schemes
In-Reply-To: <1382619026-4182-1-git-send-email-pekon@ti.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
Message-ID: <20131025105627.GB2489@localhost>

Pekon,

On Thu, Oct 24, 2013 at 06:20:16PM +0530, Pekon Gupta wrote:
> *changes v10 -> v11*
> - [PATCH v10 04/10] replaced with newer [PATCH v11 04/11] so that
>   nand_scan_ident() is called only once.
>   discussion thread with Brian Norris <computersforpeace at gmail.com>
>   <http://lists.infradead.org/pipermail/linux-mtd/2013-October/049335.html>
> - No change in any other patch
> 
> 
> *changes v9 -> v10*
> [PATCH 1/10], [PATCH 2/10]
>   swapped [PATCH v9 1/9] and [PATCH v9 2/9] so that DT parsing updates
>   (with backward compatibility) happen before the deprecation of DT values.
>   This way DTB does not break functionally between the patches.
> [PATCH 3/10] <no update>
> [PATCH 4/10] 
>   dropped [PATCH v9 4/9] introducing NAND_BUSWIDTH_AUTO, instead
>   using DT 'nand-bus-width' for device bus-width. Refer discussion thread 
>   <http://lists.infradead.org/pipermail/linux-mtd/2013-October/049198.html>
> [PATCH 5/10] <no update>
> [PATCH 6/10] <no update>
> [PATCH 7/10] 
>   separated out drivers/mtd/nand/Kconfig updates into separate [PATCH v10 10/10]
>   cleanup: s/info->nand\./nand_chip->
> [PATCH 8/10] <no update>
> [PATCH 9/10] cleanup: s/out_release_mem_region/return_error
> [PATCH 10/10] <new> spawned from [PATCH v9 8/9] for Kconfig updates
> 
> 
> *changes v8 -> v9*
> [PATCH 1/9] <no update from [PATCH v8 1/6]>
> [PATCH 2/9] <only commit log updated from [PATCH v8 2/6]>
>  As per feedbacks from Brian Norris <computersforpeace at gmail.com> previous
>  revision [PATCH v8 3/6] and [PATCH 4/6] are split into following sub-patches:
> - [PATCH 3/9] <new> replaces local reference with generic names (mtd, nand_chip)
> - [PATCH 4/9] <new> enables auto-detection of bus-width
> - [PATCH 5/9] <new> removes omap3_init_bch: populates ecc-scheme data
> - [PATCH 6/9] <new> removes omap3_init_bch_tail: populates ecc-layout
> - [PATCH 7/9] <new> replaces lib/bch.c with nand_bch.c wrapper
> [PATCH 8/9] <no update same as [PATCH v8 5/6]
> [PATCH 9/9] removed devm_free_xx functions
> 
> 
> *Changes v7 -> v8*
> [PATCH 1/6] <no updates>
> [PATCH 2/6]
> 	- updated DT parsing of "ti,nand-ecc-opts" so that its "ham1" remains
> 		compatible to "sw","hw","hw-romcode"
> 	- updated DT parsing of "ti,elm-id" to retain compatibility to "elm_id"
> 	- using of_parse_phandle() to get ELM device pointer from DT
> [PATCH 3..6/6] <commit log updates>
> 
> 
> *Changes v6 -> v7*
> [PATCH 1/6] <NEW> split from [PATCH v6 2/4] as per feedbacks from Brian Norris <computersforpeace at gmail.com>
> [PATCH 2/6] incorporated feedbacks from DT maintainers
> [PATCH 3/6] cleaned and incorporated feedbacks from Brian Norris <computersforpeace at gmail.com>
> [PATCH 4/6] rebasing changes and cleanup
> [PATCH 5/6] updated omap3430-sdp.dts
> [PATCH 6/6] <NEW> updated for devm_xx
> 
> 
> *Changes v5 -> v6*
> [PATCH 1/4]: 
> 	- updated DT binding for gpmc-nand based on 'Olof Johansson's feedbacks
> 	http://lists.infradead.org/pipermail/linux-mtd/2013-August/048394.html
> 	- detection of ELM device via ti,elm-id DT node, moved to gpmc.c driver
> [PATCH 2/4]
> 	- removed: support for following obselete ECC schemes
> 	OMAP_ECC_HAMMING_CODE_DEFAULT (S/W based 1-bit Hamming ECC)
> 	OMAP_ECC_HAMMING_CODE_HW_ROMCODE (H/W based 1-bit Hamming ECC scheme)
> 	- updated: using omap_oobinfo as chip->ecc.layout for all ecc-schemes
> 	- clean: error messages
> [PATCH 3/4] cleaned to include changes for OMAP_ECC_BCH8_CODE_HW only
> [PATCH 4/4] updated to include DT property changes
> 
> 
> *Changes v4 -> v5*
> - Rebased to linux-next 
> IMPORTANT: Need to revert commit fb1585b, [PATCH 2/4] part of previous version
> 	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047441.html
> 
> - Swapped PATCH-1 & PATCH-2 to maintain bisectibility & compilation dependency
> 	http://lists.infradead.org/pipermail/linux-mtd/2013-July/047461.html
> 
> - PATCH-2: re-ordered call to is_elm_present() for later updates ELM driver
> 	- dropped changes in include/linux/platform_data/elm.h (not needed)
> - PATCH-3: re-ordered call to is_elm_present() for later updates ELM driver
> - Re-formated patch description (replaced tabs with white-spaces)
> 
> 
> *Changes v3 -> v4*
> (Resent with CC: devicetree-discuss at lists.ozlabs.org)
> - [Patch 1/3] removed MTD_NAND_OMAP_BCH8 & MTD_NAND_OMAP_BCH4 from nand/Kconfig
> 	ECC scheme selectable via nand DT (nand-ecc-opt).
> - [*] rebased for l2-mtd.git
> 
> 
> *Changes v2 -> v3*
> (Resent with Author Name fixed)
> - PATCH-1: re-arranged code to remove redundancy, added NAND_BUSWIDTH_AUTO
> - PATCH-2: updated nand-ecc-opt DT mapping and Documentation
> - PATCH-3: code-cleaning + changes to match PATCH-1
> - PATCH-4 <DROPPED> update DT attribute for ti,nand-ecc-opt 
> 	- received feedback to keep DT mapping independent of linuxism
> - PATCH-4:<NEW> : ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
> 	- independent patch for AM335x-evm.dts update based on PATCH-2
> 
> 
> *Changes v1 -> v2*
> 	added 	[PATCH 3/4] and [PATCH 4/4]
> 
> 
> After this patch series, omap2-nand driver will supports following ECC schemes:
> +---------------------------------------+---------------+---------------+
> | ECC scheme                            |ECC calculation|Error detection|
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_HAM1_CODE_HW                  |H/W (GPMC)     |S/W            |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH4_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
> | (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
> |                                       |               |               |
> |OMAP_ECC_BCH4_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> | (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
> |        ti,elm-id)                     |               |               |
> +---------------------------------------+---------------+---------------+
> |OMAP_ECC_BCH8_CODE_HW_DETECTION_SW     |H/W (GPMC)     |S/W (lib/bch.c)|
> | (needs CONFIG_MTD_NAND_ECC_BCH)       |               |               |
> |                                       |               |               |
> |OMAP_ECC_BCH8_CODE_HW                  |H/W (GPMC)     |H/W (ELM)      |
> | (needs CONFIG_MTD_NAND_OMAP_BCH &&    |               |               |
> |        ti,elm-id)                     |               |               |
> +---------------------------------------+---------------+---------------+
> 
> 
> Pekon Gupta (10):
>   ARM: OMAP2+: cleaned-up DT support of various ECC schemes
>   mtd: nand: omap: combine different flavours of 1-bit hamming ecc
>     schemes
>   mtd: nand: omap: cleanup: replace local references with generic
>     framework names
>   mtd: nand: omap: use DT specified bus-width only for scanning NAND
>     device
>   mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in
>     device_probe
>   mtd: nand: omap: clean-up ecc layout for BCH ecc schemes
>   mtd: nand: omap: use drivers/mtd/nand/nand_bch.c wrapper for BCH ECC
>     instead of lib/bch.c
>   ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
>   mtd: nand: omap: updated devm_xx for all resource allocation and free
>     calls
>   mtd: nand: omap: remove selection of BCH ecc-scheme via KConfig
> 
>  .../devicetree/bindings/mtd/gpmc-nand.txt          |  16 +-
>  arch/arm/boot/dts/am335x-evm.dts                   |   3 +-
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   2 +-
>  arch/arm/mach-omap2/board-flash.c                  |   2 +-
>  arch/arm/mach-omap2/gpmc.c                         |  48 +-
>  drivers/mtd/nand/Kconfig                           |  40 +-
>  drivers/mtd/nand/omap2.c                           | 641 +++++++++------------
>  include/linux/platform_data/mtd-nand-omap2.h       |  18 +-
>  8 files changed, 348 insertions(+), 422 deletions(-)
> 

I tested this using the AM335x device tree you posted earlier with
the 16-bit NAND Beaglebone cape. For all the patches:

Tested-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

The ECC bindings look much much cleaner now, nice job!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Fri Oct 25 07:09:14 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 25 Oct 2013 11:09:14 +0000
Subject: [PATCH v2 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <20131025104246.GA2489@localhost>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382696277-9063-5-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AD60@DBDE04.ent.ti.com>
 <20131025104246.GA2489@localhost>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2AE0F@DBDE04.ent.ti.com>

> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> 
> Hm.. well the problem with that patch is that it's in the middle of an
> unrelated series. As I already told you, I think you should have pushed
> that as a one-patch fix. Have you seen that suggestion?
> 
Yes, I know.. actually the original patch series, when it started somewhere
April (or before) is very different from the version v11 now :-).
This devm_ update was added in middle of v6-v7 version change
(Most of the changes since first version of this patchset is captured in 
Cover-letter).


> On the other side, you're fixing too many things in that single patch,
> for my taste. Maybe I'm not the smarter developer, but going through
> that patch is not easy to catch if there's no mistake done.
> 
> Usually if it's possible to split a patch (maintaining consistency) it makes
> the reviewing process easier.
> If you'd rather send this devm_xxx change yourself that's fine by me,
> 
Ahh nothing like that.. Brian had already reviewed these couple of times
And it was only [Patch 04/10] which was last one remaining..
I just said it because this might show up in merge conflict .. or rejects..

> but *please* split the patch in two and write proper commit messages.
> 
> Anyway: this is just a silly change, the important one is the other
> nand_scan_ident() fix. Could you help me review that?
> 
> I'm interested in knowing how will that work with 8-bit and 16-bit devices.
> --
Yes, I'm just preparing the scenario where BUSWIDTH_AUTO would fail..
unless you do GPMC driver changes also.. same issue was found by
Matthieu CASTET (matthieu.castet at parrot.com)
(please see my other mail)


with regards, pekon

From pekon at ti.com  Fri Oct 25 07:15:57 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 25 Oct 2013 11:15:57 +0000
Subject: [PATCH v2 0/5] Assorted OMAP2 NAND clean-ups
In-Reply-To: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2AE2A@DBDE04.ent.ti.com>

Hi,

> -----Original Message-----
> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
[...]

> Pekon, Brian: Do you think this solution might work for 8-bit and 16-bit
> devices?
> 
I think NAND_BUSWIDTH_AUTO (without GPMC changes) would fail in
following scenarios..

Case-1: configuring gpmc,device-width=1 from DT when using x16 device.
As your NAND driver is using NAND_BUSWIDTH_AUTO, it should
ignore this DT config, and based on ONFI params it should work as x16

Case-2: configuring gpmc,device-width=2 from DT when using x8 device.
As your NAND driver is using NAND_BUSWIDTH_AUTO, it should
ignore this DT config, and based on ONFI params it should work as x8

NAND device may get detected correctly, but try doing write and read
to NAND, and I think, it would fail for Case-2 at-least.. 
Can you please check ?


> I've been going through the GPMC code again, and it looks like some cleaning
> is needed
> there two, but that's a different story!
> 
Actually having NAND_BUSWIDTH_AUTO would require change in GPMC
driver also.. please refer my comments in.. 
http://lists.infradead.org/pipermail/linux-mtd/2013-October/049284.html

reason of failure is given above...


with regards, pekon


From ezequiel.garcia at free-electrons.com  Fri Oct 25 07:19:07 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 08:19:07 -0300
Subject: [PATCH v2 4/5] mtd: nand: omap2: Use devm_kzalloc
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2AE0F@DBDE04.ent.ti.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382696277-9063-5-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AD60@DBDE04.ent.ti.com>
 <20131025104246.GA2489@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AE0F@DBDE04.ent.ti.com>
Message-ID: <20131025111906.GC2489@localhost>

On Fri, Oct 25, 2013 at 11:09:14AM +0000, Gupta, Pekon wrote:
> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> > 
> > Hm.. well the problem with that patch is that it's in the middle of an
> > unrelated series. As I already told you, I think you should have pushed
> > that as a one-patch fix. Have you seen that suggestion?
> > 
> Yes, I know.. actually the original patch series, when it started somewhere
> April (or before) is very different from the version v11 now :-).
> This devm_ update was added in middle of v6-v7 version change
> (Most of the changes since first version of this patchset is captured in 
> Cover-letter).
> 
> 

Well, in order to *avoid* having a patchset flowing for 5 months and 11
revisions you coudl try to keep series small. You could have that single
fix merged if you send it alone. Not sure why you insist in *not* doing
that.

> > On the other side, you're fixing too many things in that single patch,
> > for my taste. Maybe I'm not the smarter developer, but going through
> > that patch is not easy to catch if there's no mistake done.
> > 
> > Usually if it's possible to split a patch (maintaining consistency) it makes
> > the reviewing process easier.
> > If you'd rather send this devm_xxx change yourself that's fine by me,
> > 
> Ahh nothing like that.. Brian had already reviewed these couple of times

Ah, good. In that case you should add "Reviewed-by" if Brian already
reviewed it. IMHO, the patch could be cleaner and the commit message
could be better.

> And it was only [Patch 04/10] which was last one remaining..

Yes, and because you added *another* patch to the series you keep
spinning patchset versions.

> I just said it because this might show up in merge conflict .. or rejects..
> 
> > but *please* split the patch in two and write proper commit messages.
> > 
> > Anyway: this is just a silly change, the important one is the other
> > nand_scan_ident() fix. Could you help me review that?
> > 
> > I'm interested in knowing how will that work with 8-bit and 16-bit devices.
> > --
> Yes, I'm just preparing the scenario where BUSWIDTH_AUTO would fail..
> unless you do GPMC driver changes also.. same issue was found by
> Matthieu CASTET (matthieu.castet at parrot.com)
> (please see my other mail)
> 

OK, let's try to focus in that patch alone, I'd like to move forward.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From pekon at ti.com  Fri Oct 25 07:26:06 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Fri, 25 Oct 2013 11:26:06 +0000
Subject: [PATCH v2 3/5] mtd: nand: omap2: Fix OMAP_BCH option dependency
In-Reply-To: <1382696277-9063-4-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382696277-9063-4-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2AE93@DBDE04.ent.ti.com>

> From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> Subject: [PATCH v2 3/5] mtd: nand: omap2: Fix OMAP_BCH option
> dependency
> 
> This option does not need to depend in MTD_NAND, for it's enclosed
> under it. Also, it's wrong to make it depend in ARCH_OMAP3 only
> since the controller is used in a wider range of SoCs.
> 
> Instead, just leave the dependency on the OMAP2 driver option.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> ---
>  drivers/mtd/nand/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> index d885298..8187466 100644
> --- a/drivers/mtd/nand/Kconfig
> +++ b/drivers/mtd/nand/Kconfig
> @@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
>  	  platforms.
> 
>  config MTD_NAND_OMAP_BCH
> -	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
> +	depends on MTD_NAND_OMAP2
>  	tristate "Enable support for hardware BCH error correction"
>  	default n
>  	select BCH
> --
> 1.8.1.5

Acked-by: Pekon Gupta <pekon at ti.com>
Reported-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

with regards, pekon


From ezequiel.garcia at free-electrons.com  Fri Oct 25 07:48:37 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 08:48:37 -0300
Subject: [PATCH v2 0/5] Assorted OMAP2 NAND clean-ups
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2AE2A@DBDE04.ent.ti.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AE2A@DBDE04.ent.ti.com>
Message-ID: <20131025114836.GD2489@localhost>

Pekon,

On Fri, Oct 25, 2013 at 11:15:57AM +0000, Gupta, Pekon wrote:
> Hi,
> 
> > -----Original Message-----
> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> [...]
> 
> > Pekon, Brian: Do you think this solution might work for 8-bit and 16-bit
> > devices?
> > 
> I think NAND_BUSWIDTH_AUTO (without GPMC changes) would fail in
> following scenarios..
> 
> Case-1: configuring gpmc,device-width=1 from DT when using x16 device.

... which is wrong. That's why we have a DT property to configure that.
The GPMC *must* be properly configured.

> As your NAND driver is using NAND_BUSWIDTH_AUTO, it should
> ignore this DT config, and based on ONFI params it should work as x16
> 

Hm.. I don't think so. The auto-stuff is just for the NAND driver, not
for the memory controller. I don't know much about hardware, but in my mind
I imagine them as different controllers.

> Case-2: configuring gpmc,device-width=2 from DT when using x8 device.

... which is also wrong.

Once again, you're mis-configuring the GPMC. We cannot expect the NAND
driver to work properly if the GPMC is not properly initialized, don't
you think?

> Actually having NAND_BUSWIDTH_AUTO would require change in GPMC
> driver also.. please refer my comments in.. 
> http://lists.infradead.org/pipermail/linux-mtd/2013-October/049284.html
> 

Well, I think the approach should be different and much simpler: GPMC
*must* be properly configured and then NAND can do ONFI detection
starting in 8-bit and then switching to 16-bit if needed.

This is what this patch is doing: it _fixes_ the NAND driver ONFI detection,
_provided_ the GPMC is well-prepared.

You seem to think that GPMC + NAND should be able to automagically detect
the device and work, but I don't think that's even physically possible, for
the reasons you have just exposed.

I think this fix is simple enough.

BTW: The GPMC code ignores the DT value in 'gpmc,device-width' and uses
'nand-bus-width' instead, but that's a different bug and a different fix :)
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Fri Oct 25 07:49:55 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 08:49:55 -0300
Subject: [PATCH v2 3/5] mtd: nand: omap2: Fix OMAP_BCH option dependency
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2AE93@DBDE04.ent.ti.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <1382696277-9063-4-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AE93@DBDE04.ent.ti.com>
Message-ID: <20131025114954.GE2489@localhost>

On Fri, Oct 25, 2013 at 11:26:06AM +0000, Gupta, Pekon wrote:
> > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> > Subject: [PATCH v2 3/5] mtd: nand: omap2: Fix OMAP_BCH option
> > dependency
> > 
> > This option does not need to depend in MTD_NAND, for it's enclosed
> > under it. Also, it's wrong to make it depend in ARCH_OMAP3 only
> > since the controller is used in a wider range of SoCs.
> > 
> > Instead, just leave the dependency on the OMAP2 driver option.
> > 
> > Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> > ---
> >  drivers/mtd/nand/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> > index d885298..8187466 100644
> > --- a/drivers/mtd/nand/Kconfig
> > +++ b/drivers/mtd/nand/Kconfig
> > @@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
> >  	  platforms.
> > 
> >  config MTD_NAND_OMAP_BCH
> > -	depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
> > +	depends on MTD_NAND_OMAP2
> >  	tristate "Enable support for hardware BCH error correction"
> >  	default n
> >  	select BCH
> > --
> > 1.8.1.5
> 
> Acked-by: Pekon Gupta <pekon at ti.com>

Thanks!

> Reported-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
> 

FWIW, If I'm signing-off this commit, it's implicit that I'm the
reporter.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From caizhiyong at hisilicon.com  Fri Oct 25 07:52:14 2013
From: caizhiyong at hisilicon.com (Caizhiyong)
Date: Fri, 25 Oct 2013 11:52:14 +0000
Subject: [PATCH] mtd: cmdlinepart: use cmdline partition parser lib
In-Reply-To: <20131020120603.GA18678@localhost>
References: <C3050A4DBA34F345975765E43127F10F1C0643B8@szxeml512-mbx.china.huawei.com>
 <20131020120603.GA18678@localhost>
Message-ID: <C3050A4DBA34F345975765E43127F10F1C084F26@szxeml512-mbs.china.huawei.com>

> 
> I'd like to review the patch in detail and test it, but being a bit old,
> the patch doesn't apply as it is on v3.12-rc5. Care to resend an update?
>
  I have sent you a 2 patch base on v3.12-rc6. Are there any problems? I tested it for a long time and found no problems.

  Are there any plans for supporting synchronous NAND in the future?

 
> Brian: I saw you want to move forward with this. I guess we can give
> it a test, and if all the possible 'mtdparts' use cases work, then
> we shouldn't object the cleanup, right?
> --
> Ezequiel Garc?a, Free Electrons
> Embedded Linux, Kernel and Android Engineering
> http://free-electrons.com

From dwmw2 at infradead.org  Fri Oct 25 08:03:27 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Fri, 25 Oct 2013 13:03:27 +0100
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382602484-12023-1-git-send-email-b32955@freescale.com>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
Message-ID: <1382702607.8522.110.camel@shinybook.infradead.org>

On Thu, 2013-10-24 at 16:14 +0800, Huang Shijie wrote:
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> -       return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
> +       return legacy_set_geometry(this) ? set_geometry_by_ecc_info(this) : 0;

So... what if someone has already shipped the new chips that require
stronger ECC, without realising that legacy_set_geometry() is
insufficient? (And is legacy_set_geometry *actually* doing precisely the
same as 3.10/3.11?)

Do we forcibly upgrade them to the new method, and compatibility be
damned?

I'm inclined to suggest that for the 3.12 release we just need to use
legacy_set_geometry(), and allow it to work with a *warning*, and then
for 3.13 we can finish thrashing out the precise behaviour we need ?
which may indeed end up being that you do the new method *only* if the
corresponding property exists in the device tree.

-- 
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: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131025/363d61e4/attachment.bin>

From ezequiel.garcia at free-electrons.com  Fri Oct 25 08:09:01 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Fri, 25 Oct 2013 09:09:01 -0300
Subject: [PATCH] mtd: cmdlinepart: use cmdline partition parser lib
In-Reply-To: <C3050A4DBA34F345975765E43127F10F1C084F26@szxeml512-mbs.china.huawei.com>
References: <C3050A4DBA34F345975765E43127F10F1C0643B8@szxeml512-mbx.china.huawei.com>
 <20131020120603.GA18678@localhost>
 <C3050A4DBA34F345975765E43127F10F1C084F26@szxeml512-mbs.china.huawei.com>
Message-ID: <20131025120900.GF2489@localhost>

Hi,

On Fri, Oct 25, 2013 at 11:52:14AM +0000, Caizhiyong wrote:
> > 
> > I'd like to review the patch in detail and test it, but being a bit old,
> > the patch doesn't apply as it is on v3.12-rc5. Care to resend an update?
> >
>   I have sent you a 2 patch base on v3.12-rc6. Are there any problems? I tested it for a long time and found no problems.
> 

I haven't had time to look at that yet, thanks for re-sending them!

If you already did testing using those, then I think we would all appreciate
that you post the results.

In particular, we're interested in **seeing** this change parses correctly
all possible combinations of partitions configured by the 'mtdparts' parameter.

This is a big change you're proposing and we need to be sure there won't
be any users experiencing any unexpected result while using 'mtdparts'.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From dwmw2 at infradead.org  Fri Oct 25 08:20:54 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Fri, 25 Oct 2013 13:20:54 +0100
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382702607.8522.110.camel@shinybook.infradead.org>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
Message-ID: <1382703654.8522.114.camel@shinybook.infradead.org>

On Fri, 2013-10-25 at 13:03 +0100, David Woodhouse wrote:
> 
> So... what if someone has already shipped the new chips that require
> stronger ECC, without realising that legacy_set_geometry() is
> insufficient? (And is legacy_set_geometry *actually* doing precisely the
> same as 3.10/3.11?)

Answering my own question: If the required ECC strength is known and the
legacy ECC layout is insufficient, that's caused a failure since commit
92d0e09abeebd ("mtd: gpmi: add sanity check for the ECC") in 3.9, so I'm
not worried about supporting that.

And legacy_set_geometry() *is* doing what 3.11 did, verbatim.

So the question is whether we want this "if legacy is sufficient then
use it else use the new method" that you offer in v2 of the patch, or if
a device-tree property is the better way to do it.

I'm actually slightly in favour of the device-tree property. But since
3.12 is imminent I think the *best* option is just to do this to
preserve the 3.11 behaviour, and worry about getting it right for 3.13:

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 59ab069..a9830ff 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -349,7 +349,7 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
-	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
+	return legacy_set_geometry(this);
 }
 
 struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)


-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131025/c6ccafa2/attachment.bin>

From marex at denx.de  Fri Oct 25 09:22:12 2013
From: marex at denx.de (Marek)
Date: Fri, 25 Oct 2013 15:22:12 +0200
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382703654.8522.114.camel@shinybook.infradead.org>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
 <1382703654.8522.114.camel@shinybook.infradead.org>
Message-ID: <1759334.BdWLZMGAMu@w510>

On Friday 25 of October 2013 13:20:54 David Woodhouse wrote:
> On Fri, 2013-10-25 at 13:03 +0100, David Woodhouse wrote:
> > So... what if someone has already shipped the new chips that require
> > stronger ECC, without realising that legacy_set_geometry() is
> > insufficient? (And is legacy_set_geometry *actually* doing precisely the
> > same as 3.10/3.11?)
> 
> Answering my own question: If the required ECC strength is known and the
> legacy ECC layout is insufficient, that's caused a failure since commit
> 92d0e09abeebd ("mtd: gpmi: add sanity check for the ECC") in 3.9, so I'm
> not worried about supporting that.
> 
> And legacy_set_geometry() *is* doing what 3.11 did, verbatim.
> 
> So the question is whether we want this "if legacy is sufficient then
> use it else use the new method" that you offer in v2 of the patch, or if
> a device-tree property is the better way to do it.
> 
> I'm actually slightly in favour of the device-tree property. But since
> 3.12 is imminent I think the *best* option is just to do this to
> preserve the 3.11 behaviour, and worry about getting it right for 3.13:
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 59ab069..a9830ff 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -349,7 +349,7 @@ static int legacy_set_geometry(struct gpmi_nand_data
> *this)
> 
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> -	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
> +	return legacy_set_geometry(this);
>  }
> 
>  struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)

I can confirm this patch fixes the regression, UBIFS can now again be mounted on 
3.12rc6 . Thanks!

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

On M28EVK with NAND device:
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xda (Micron MT29F2G08ABAEAWP)
NAND device: 256MiB, SLC, page size: 2048, OOB size: 64

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

Cheers!


From shijie8 at gmail.com  Fri Oct 25 21:33:00 2013
From: shijie8 at gmail.com (Huang Shijie)
Date: Fri, 25 Oct 2013 21:33:00 -0400
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382703654.8522.114.camel@shinybook.infradead.org>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
 <1382703654.8522.114.camel@shinybook.infradead.org>
Message-ID: <20131026013258.GA3195@gmail.com>

On Fri, Oct 25, 2013 at 01:20:54PM +0100, David Woodhouse wrote:
> On Fri, 2013-10-25 at 13:03 +0100, David Woodhouse wrote:
> > 
> > So... what if someone has already shipped the new chips that require
> > stronger ECC, without realising that legacy_set_geometry() is
> > insufficient? (And is legacy_set_geometry *actually* doing precisely the
> > same as 3.10/3.11?)
> 
> Answering my own question: If the required ECC strength is known and the
> legacy ECC layout is insufficient, that's caused a failure since commit
> 92d0e09abeebd ("mtd: gpmi: add sanity check for the ECC") in 3.9, so I'm
> not worried about supporting that.
> 
> And legacy_set_geometry() *is* doing what 3.11 did, verbatim.
> 
> So the question is whether we want this "if legacy is sufficient then
> use it else use the new method" that you offer in v2 of the patch, or if
> a device-tree property is the better way to do it.
> 
> I'm actually slightly in favour of the device-tree property. But since
> 3.12 is imminent I think the *best* option is just to do this to
> preserve the 3.11 behaviour, and worry about getting it right for 3.13:

Hi David:
  I am ok with your patch. but we will meet a compiler warning, since
  the set_geometry_by_ecc_info() is not referenced.

  thanks
  Huang Shijie
  
> 
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 59ab069..a9830ff 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -349,7 +349,7 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
>  
>  int common_nfc_set_geometry(struct gpmi_nand_data *this)
>  {
> -	return set_geometry_by_ecc_info(this) ? 0 : legacy_set_geometry(this);
> +	return legacy_set_geometry(this);
>  }
>  
>  struct dma_chan *get_dma_chan(struct gpmi_nand_data *this)
> 
> 
> -- 
> dwmw2
> 



> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From dwmw2 at infradead.org  Fri Oct 25 09:29:42 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Fri, 25 Oct 2013 14:29:42 +0100
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <20131026013258.GA3195@gmail.com>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
 <1382703654.8522.114.camel@shinybook.infradead.org>
 <20131026013258.GA3195@gmail.com>
Message-ID: <1382707782.8522.140.camel@shinybook.infradead.org>

On Fri, 2013-10-25 at 21:33 -0400, Huang Shijie wrote:
> 
>   I am ok with your patch. but we will meet a compiler warning, since
>   the set_geometry_by_ecc_info() is not referenced.

Yeah, I predicted that but at this stage with *hours* to catch Linux and
get it into 3.12, I think that's the better option. I'll note it in the
commit comment.

Thanks for the prompt feedback.

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131025/a0c22476/attachment-0001.bin>

From dwmw2 at infradead.org  Fri Oct 25 09:36:34 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Fri, 25 Oct 2013 14:36:34 +0100
Subject: [PATCH v2 fix] mtd: gpmi: fix the ecc regression
In-Reply-To: <20131024221920.GF20061@ld-irv-0074.broadcom.com>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382604496-28118-1-git-send-email-b32955@freescale.com>
 <20131024221920.GF20061@ld-irv-0074.broadcom.com>
Message-ID: <1382708194.8522.145.camel@shinybook.infradead.org>

On Thu, 2013-10-24 at 15:19 -0700, Brian Norris wrote:
> I fixed up the language a little, dropped the 'stable', and pushed to
> linux-mtd.git (in hopes of sending another pull request for 3.12). I'll
> see if David wants to weigh in first.

You're fine. Go ahead and send the request if you're happy to do so.

Thanks.

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131025/97db7f0a/attachment.bin>

From shijie8 at gmail.com  Fri Oct 25 21:41:17 2013
From: shijie8 at gmail.com (Huang Shijie)
Date: Fri, 25 Oct 2013 21:41:17 -0400
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382707782.8522.140.camel@shinybook.infradead.org>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
 <1382703654.8522.114.camel@shinybook.infradead.org>
 <20131026013258.GA3195@gmail.com>
 <1382707782.8522.140.camel@shinybook.infradead.org>
Message-ID: <20131026014115.GB3195@gmail.com>

On Fri, Oct 25, 2013 at 02:29:42PM +0100, David Woodhouse wrote:
> On Fri, 2013-10-25 at 21:33 -0400, Huang Shijie wrote:
> > 
> >   I am ok with your patch. but we will meet a compiler warning, since
> >   the set_geometry_by_ecc_info() is not referenced.
> 
> Yeah, I predicted that but at this stage with *hours* to catch Linux and
> get it into 3.12, I think that's the better option. I'll note it in the
> commit comment.

ok. Please add my ack for your formal patch:
Acked-by: Huang Shijie <shijie8 at gmail.com>



From marex at denx.de  Fri Oct 25 09:38:37 2013
From: marex at denx.de (Marek)
Date: Fri, 25 Oct 2013 15:38:37 +0200
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382707782.8522.140.camel@shinybook.infradead.org>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <20131026013258.GA3195@gmail.com>
 <1382707782.8522.140.camel@shinybook.infradead.org>
Message-ID: <1840834.G3nI0UQ6lx@w510>

On Friday 25 of October 2013 14:29:42 David Woodhouse wrote:
> On Fri, 2013-10-25 at 21:33 -0400, Huang Shijie wrote:
> >   I am ok with your patch. but we will meet a compiler warning, since
> >   the set_geometry_by_ecc_info() is not referenced.
> 
> Yeah, I predicted that but at this stage with *hours* to catch Linux and
> get it into 3.12, I think that's the better option. I'll note it in the
> commit comment.
> 
> Thanks for the prompt feedback.

Might __maybe_unused help here ?


From dwmw2 at infradead.org  Fri Oct 25 10:08:12 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Fri, 25 Oct 2013 15:08:12 +0100
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <20131026014115.GB3195@gmail.com>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
 <1382703654.8522.114.camel@shinybook.infradead.org>
 <20131026013258.GA3195@gmail.com>
 <1382707782.8522.140.camel@shinybook.infradead.org>
 <20131026014115.GB3195@gmail.com>
Message-ID: <1382710092.8395.3.camel@shinybook.infradead.org>

On Fri, 2013-10-25 at 21:41 -0400, Huang Shijie wrote:
> On Fri, Oct 25, 2013 at 02:29:42PM +0100, David Woodhouse wrote:
> > On Fri, 2013-10-25 at 21:33 -0400, Huang Shijie wrote:
> > > 
> > >   I am ok with your patch. but we will meet a compiler warning, since
> > >   the set_geometry_by_ecc_info() is not referenced.
> > 
> > Yeah, I predicted that but at this stage with *hours* to catch Linux and
> > get it into 3.12, I think that's the better option. I'll note it in the
> > commit comment.
> 
> ok. Please add my ack for your formal patch:
> Acked-by: Huang Shijie <shijie8 at gmail.com>

I've just pushed this to the tip of the tree, replacing the version that
Brian had put there.

Brian, are you still happy to send the pull request to Linus or do you
want me to?


-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131025/7a4446b3/attachment.bin>

From computersforpeace at gmail.com  Fri Oct 25 13:08:06 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 25 Oct 2013 10:08:06 -0700
Subject: [PATCH V2] mtd: gpmi: fix the ecc regression
In-Reply-To: <1382710092.8395.3.camel@shinybook.infradead.org>
References: <1382602484-12023-1-git-send-email-b32955@freescale.com>
 <1382702607.8522.110.camel@shinybook.infradead.org>
 <1382703654.8522.114.camel@shinybook.infradead.org>
 <20131026013258.GA3195@gmail.com>
 <1382707782.8522.140.camel@shinybook.infradead.org>
 <20131026014115.GB3195@gmail.com>
 <1382710092.8395.3.camel@shinybook.infradead.org>
Message-ID: <CAN8TOE9VtpJfvTQdYW-POJXOshoQPNsE0gHiNkG4v5-E2=EkkQ@mail.gmail.com>

On Fri, Oct 25, 2013 at 7:08 AM, David Woodhouse <dwmw2 at infradead.org> wrote:
> On Fri, 2013-10-25 at 21:41 -0400, Huang Shijie wrote:
>> On Fri, Oct 25, 2013 at 02:29:42PM +0100, David Woodhouse wrote:
>> > On Fri, 2013-10-25 at 21:33 -0400, Huang Shijie wrote:
>> > >
>> > >   I am ok with your patch. but we will meet a compiler warning, since
>> > >   the set_geometry_by_ecc_info() is not referenced.
>> >
>> > Yeah, I predicted that but at this stage with *hours* to catch Linux and
>> > get it into 3.12, I think that's the better option. I'll note it in the
>> > commit comment.
>>
>> ok. Please add my ack for your formal patch:
>> Acked-by: Huang Shijie <shijie8 at gmail.com>
>
> I've just pushed this to the tip of the tree, replacing the version that
> Brian had put there.

A tiny comment on the description. You say:

"The "legacy" ECC layout used until 3.11 uses all the OOB area by
computing the ECC strength and ECC step size ourselves."

This phrase "until 3.11" sounds like the layout changed in 3.11 (which
it did not). The rest of the commit message might clear that up, but
still...

> Brian, are you still happy to send the pull request to Linus or do you
> want me to?

I'm happy either way, as long as the fixes go in. I'll send it, since
I still have the day ahead of me in my timezone.

Thanks,
Brian


From computersforpeace at gmail.com  Fri Oct 25 13:32:15 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 25 Oct 2013 10:32:15 -0700
Subject: [GIT PULL] final MTD fixes for 3.12
Message-ID: <20131025173215.GH20061@ld-irv-0074.broadcom.com>

Hi Linus,

Can you please pull a few more MTD regression fixes for 3.12?

I signed my tag this time, although you still have little reason to trust
it.

Thanks,
Brian

The following changes since commit b291a22952e74bb2fcf9c57c6d8bae52a4f197e2:

  Merge tag 'for-linus-20131008' of git://git.infradead.org/linux-mtd (2013-10-10 11:30:33 -0700)

are available in the git repository at:

  git://git.infradead.org/linux-mtd.git tags/for-linus-20131025

for you to fetch changes up to 031e2777e03401d629e62602c8ce42b017732d4d:

  mtd: gpmi: fix ECC regression (2013-10-25 10:09:43 -0700)

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

A few more last-minute regression fixes, prepared jointly by me and David
Woodhouse:

* Revert pxa3xx to its old name to avoid breaking existing 'mtdparts=' boot
  strings.

* Return GPMI NAND to its legacy ECC layout for backwards compatibility. We
  will revisit this in 3.13.

A note from David on the latter fix: "This leaves a harmless cosmetic warning
about an unused function. At this point in the cycle I really don't care."

----------------------------------------------------------------
David Woodhouse (1):
      mtd: gpmi: fix ECC regression

Ezequiel Garcia (1):
      mtd: nand: pxa3xx: Fix registered MTD name

 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 2 +-
 drivers/mtd/nand/pxa3xx_nand.c         | 7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)


From computersforpeace at gmail.com  Fri Oct 25 13:59:47 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 25 Oct 2013 10:59:47 -0700
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131025175947.GI20061@ld-irv-0074.broadcom.com>

On Wed, Oct 23, 2013 at 07:58:22PM -0700, Brian Norris wrote:
> Remove the compile-time option for FAST_READ, since we have run-time
> support for detecting it.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>

Pushed to l2-mtd.git. Comments are still welcome.

FYI Huang: Sourav's new quad read patch applies on top of this patch.

Brian


From computersforpeace at gmail.com  Fri Oct 25 14:01:09 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Fri, 25 Oct 2013 11:01:09 -0700
Subject: [PATCH 5/5] mtd: m25p80: remove 'disabled' device check
In-Reply-To: <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-5-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131025180109.GJ20061@ld-irv-0074.broadcom.com>

On Wed, Oct 23, 2013 at 07:58:23PM -0700, Brian Norris wrote:
> It seems like the following commit was never necessary
> 
>     commit 5f949137952020214cd167093dd7be448f21c079
>     Author: Shaohui Xie <Shaohui.Xie at freescale.com>
>     Date:   Fri Oct 14 15:49:00 2011 +0800
> 
>         mtd: m25p80: don't probe device which has status of 'disabled'
> 
> because it duplicates the code in of_platform_device_create_pdata()
> which ensures that 'disabled' nodes are never instantiated.
> 
> Also, drop the __maybe_unused.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Cc: Grant Likely <grant.likely at linaro.org>
> Cc: Rob Herring <rob.herring at calxeda.com>
> Cc: <devicetree at vger.kernel.org>

Pushed to l2-mtd.git.

Brian


From dwmw2 at infradead.org  Fri Oct 25 19:46:48 2013
From: dwmw2 at infradead.org (David Woodhouse)
Date: Sat, 26 Oct 2013 00:46:48 +0100
Subject: [GIT PULL] final MTD fixes for 3.12
In-Reply-To: <20131025173215.GH20061@ld-irv-0074.broadcom.com>
References: <20131025173215.GH20061@ld-irv-0074.broadcom.com>
Message-ID: <1382744808.2086.6.camel@shinybook.infradead.org>

On Fri, 2013-10-25 at 10:32 -0700, Brian Norris wrote:
> Hi Linus,
> 
> Can you please pull a few more MTD regression fixes for 3.12?
> 
> I signed my tag this time, although you still have little reason to
> trust it.

Thanks, Brian.

Where in the -0700 time zone are you, btw? I really ought to buy you
beer *and* sign your key at some point...

(Reply-to set)

-- 
dwmw2

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5745 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131026/b4168ead/attachment.bin>

From dedekind1 at gmail.com  Sat Oct 26 05:19:24 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sat, 26 Oct 2013 10:19:24 +0100
Subject: nor flash used in UBIFS
In-Reply-To: <71CF8D7F32C5C24C9CD1D0E02D52498A770AED67@NTXXIAMBX02.xacn.micron.com>
References: <71CF8D7F32C5C24C9CD1D0E02D52498A77082AC5@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A77082DDB@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED11@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED44@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED67@NTXXIAMBX02.xacn.micron.com>
Message-ID: <1382779164.5901.1.camel@karhu.quadriga.com>

On Thu, 2013-10-10 at 08:28 +0000, Qi Wang ?? (qiwang) wrote:
> But I want to say the potential risk is if low level driver program data to 
> this block, it will get ?timeout error?. And the timeout period could be very 
> long(almost several minutes), during this period, any operation on NOR flash 
> cannot be accept. so program data to a erasure interrupted block isn?t a 
> sensible action. in order to avoid program a erasure interrupted block, 
> I suggest UBIFS can read this block before program data. the code changing as below:

Yes, reading first sounds like a good idea. Would you please send a
patch implementing it?

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Sat Oct 26 05:47:50 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sat, 26 Oct 2013 10:47:50 +0100
Subject: [PATCH] ubi: attach: do not return -EINVAL if the
 mtd->numeraseregions is 1
In-Reply-To: <1379470659-12158-1-git-send-email-b32955@freescale.com>
References: <1379470659-12158-1-git-send-email-b32955@freescale.com>
Message-ID: <1382780870.5901.20.camel@karhu.quadriga.com>

On Wed, 2013-09-18 at 10:17 +0800, Huang Shijie wrote:
> -	if (ubi->mtd->numeraseregions != 0) {
> +	if (ubi->mtd->numeraseregions > 1) {

The purpose of this code is to refuse "composite" mtd devices, simply
because UBIFS authors never had any of them and did not know how to deal
with them.

numeraseregions == 0 means "no erase regions". This is the ABI, as we
expose this piece of information via sysfs, see
"Documentation/ABI/testing/sysfs-class-mtd".

numeraseregions > 1 means that this is some kind of a composite flash
consisting of several regions with different eraseblock sizes. I've
never saw these, but I guess there is always one large "main" region and
some small special-purpose regions.

What is 'numeraseregions == 1'? How is it different to 'numeraseregions
== 0'?

Is the "main" area covered by mtd->size, or 'mtd->size' spans the entire
chip and includes all the regions?

What is the flash you are dealing with? Surely this is not gpmi-nand?

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Sat Oct 26 06:14:45 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sat, 26 Oct 2013 11:14:45 +0100
Subject: [PATCH] UBIFS: fix error return code in ubifs_remount_rw() and
 ubifs_fill_super()
In-Reply-To: <CAN8TOE96Ax_gyeG5fXHejHE6gCmxNchioy1BrE8a6B83kK7A8g@mail.gmail.com>
References: <CAPgLHd_=Y=YwCWSFjcacJ14yKUidmmJTHnKKibU6haoBUeNacA@mail.gmail.com>
 <CAN8TOE96Ax_gyeG5fXHejHE6gCmxNchioy1BrE8a6B83kK7A8g@mail.gmail.com>
Message-ID: <1382782485.5901.22.camel@karhu.quadriga.com>


On Wed, 2013-10-02 at 12:59 -0700, Brian Norris wrote:
> Bump, Artem? I'm cleaning out my old email, and this patch looks
> obviously correct.

Picked to linux-ubifs.git, thanks!

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Sat Oct 26 06:17:52 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sat, 26 Oct 2013 11:17:52 +0100
Subject: Patching mkfs.ubifs.c for running under Windows ?
In-Reply-To: <7c74c0d714e8e87daebbfd0163642d71@localhost>
References: <mailman.6.1379692801.23497.linux-mtd@lists.infradead.org>
 <7c74c0d714e8e87daebbfd0163642d71@localhost>
Message-ID: <1382782672.5901.25.camel@karhu.quadriga.com>

On Sat, 2013-09-21 at 12:58 +0200, gutemine wrote:
> As users of ubidump under Windows now asked me for getting also the
> possibility to re-pack their extracted ubifs images, I'm considering to
> patch mkfs.ubifs.c, so that it handles also the Windows hard and softlinks
> and my dummy device files correctly.

Generally, I am OK with making the code support windows, why not? But
this should be done very nicely and should not be intrusive. I guess you
should send patches and then we'll see.

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Sat Oct 26 06:26:21 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sat, 26 Oct 2013 11:26:21 +0100
Subject: [PATCH] mtd-utils: Makefile: add LDFLAGS_mkfs.ubifs
In-Reply-To: <a8879fac-dd29-4ed5-8977-89aec49473f2@zimbra>
References: <a8879fac-dd29-4ed5-8977-89aec49473f2@zimbra>
Message-ID: <1382783181.5901.26.camel@karhu.quadriga.com>

On Fri, 2013-09-27 at 11:34 -0500, Aaron Sierra wrote:
> The build rule for mkfs.ubifs was missing an LDFLAGS_* variable like
> mkfs.jffs2 had. This prevented mkfs.ubifs from being built against
> explicit external libraries which is needed when cross-compiling.
> 
> This also adds UUIDCPPFLAGS and UUIDLDFLAGS variables to support the
> mkfs.ubifs build.
> 
> Signed-off-by: Aaron Sierra <asierra at xes-inc.com>

Looks good, pushed to mtd-utils.git, thank you!

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Sat Oct 26 06:35:07 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Sat, 26 Oct 2013 11:35:07 +0100
Subject: [PATCH] ubifs: Correct data corruption range
In-Reply-To: <ED3E0BCACD909541BA94A34C4A164D4C4FCDE5DF@post.tritech.se>
References: <ED3E0BCACD909541BA94A34C4A164D4C4FCDE5DF@post.tritech.se>
Message-ID: <1382783707.5901.27.camel@karhu.quadriga.com>

On Wed, 2013-08-21 at 13:24 +0000, Mats K?rrman wrote:
> With power-cut emulation, it is possible that sometimes no data at all is
> corrupted and that confusing messages are printed due to errors in the
> computation of data corruption range.
> 
> [1] The start of the range should be [0..len-1], not [0..len].
> [2] The end of the range should always be at least 1 greater than the start.
> 
> Signed-off-by: Mats Karrman <mats.karrman at tritech.se>

Picked to linux-ubifs.git, thanks!

-- 
Best Regards,
Artem Bityutskiy



From marex at denx.de  Sun Oct 27 12:30:11 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 17:30:11 +0100
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
In-Reply-To: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <201310271730.12065.marex@denx.de>

Hi Brian,

[...]

> @@ -1137,14 +1135,10 @@ static int m25p_probe(struct spi_device *spi)
>  static int m25p_remove(struct spi_device *spi)
>  {
>  	struct m25p	*flash = spi_get_drvdata(spi);
> -	int		status;
> 
>  	/* Clean up MTD stuff. */
> -	status = mtd_device_unregister(&flash->mtd);
> -	if (status == 0) {
> -		kfree(flash->command);
> -		kfree(flash);
> -	}
> +	mtd_device_unregister(&flash->mtd);
> +
>  	return 0;
>  }

I wonder if we shouldn't return "status" in here in case mtd_device_unregister() 
failed.

Best regards,
Marek Vasut


From marex at denx.de  Sun Oct 27 12:30:52 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 17:30:52 +0100
Subject: [PATCH 2/5] mtd: m25p80: remove obsolete FIXME
In-Reply-To: <1382583503-13748-2-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-2-git-send-email-computersforpeace@gmail.com>
Message-ID: <201310271730.52634.marex@denx.de>

Hi Brian,

> The FIXME and NOTE have already been fixed (we have FAST_READ support).
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> ---
>  drivers/mtd/devices/m25p80.c | 9 ---------
>  1 file changed, 9 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 63a95ac..7c4cbad 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -367,10 +367,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t
> from, size_t len, spi_message_init(&m);
>  	memset(t, 0, (sizeof t));
> 
> -	/* NOTE:
> -	 * OPCODE_FAST_READ (if available) is faster.
> -	 * Should add 1 byte DUMMY_BYTE.
> -	 */
>  	t[0].tx_buf = flash->command;
>  	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
>  	spi_message_add_tail(&t[0], &m);
> @@ -388,11 +384,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t
> from, size_t len, return 1;
>  	}
> 
> -	/* FIXME switch to OPCODE_FAST_READ.  It's required for higher
> -	 * clocks; and at this writing, every chip this driver handles
> -	 * supports that opcode.
> -	 */
> -
>  	/* Set up the write data buffer. */
>  	opcode = flash->read_opcode;
>  	flash->command[0] = opcode;

Makes great share of sense ;-)

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

Best regards,
Marek Vasut


From marex at denx.de  Sun Oct 27 12:32:42 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 17:32:42 +0100
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
Message-ID: <201310271732.42518.marex@denx.de>

Hi Brian,

> Remove the compile-time option for FAST_READ, since we have run-time
> support for detecting it.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> ---
>  drivers/mtd/devices/Kconfig  |  7 -------
>  drivers/mtd/devices/m25p80.c | 11 ++++++-----
>  2 files changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> index 74ab4b7..0128138 100644
> --- a/drivers/mtd/devices/Kconfig
> +++ b/drivers/mtd/devices/Kconfig
> @@ -95,13 +95,6 @@ config MTD_M25P80
>  	  if you want to specify device partitioning or to use a device which
>  	  doesn't support the JEDEC ID instruction.
> 
> -config M25PXX_USE_FAST_READ
> -	bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz"
> -	depends on MTD_M25P80
> -	default y
> -	help
> -	  This option enables FAST_READ access supported by ST M25Pxx.
> -
>  config MTD_SPEAR_SMI
>  	tristate "SPEAR MTD NOR Support through SMI controller"
>  	depends on PLAT_SPEAR
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 7e3ec7a..d6c5c57 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
>  	flash->page_size = info->page_size;
>  	flash->mtd.writebufsize = flash->page_size;
> 
> -	flash->fast_read = false;
> -	if (np && of_property_read_bool(np, "m25p,fast-read"))
> +	if (np)
> +		/* If we were instantiated by DT, use it */
> +		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
> +	else
> +		/* If we weren't instantiated by DT, default to fast-read */
>  		flash->fast_read = true;

We should default to FALSE , unless explicitly requested by DT, am I wrong? 
Otherwise this might break the old chips.

[...]

Best regards,
Marek Vasut


From marex at denx.de  Sun Oct 27 12:45:16 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 17:45:16 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <201310271745.17152.marex@denx.de>

Dear Sourav Poddar,

[...]

> +static int macronix_quad_enable(struct m25p *flash)
> +{
> +	int ret, val;
> +	u8 cmd[2];
> +	cmd[0] = OPCODE_WRSR;
> +
> +	val = read_sr(flash);
> +	cmd[1] = val | SR_QUAD_EN_MX;
> +	write_enable(flash);
> +
> +	spi_write(flash->spi, &cmd, 2);
> +
> +	if (wait_till_ready(flash))
> +		return 1;
> +
> +	ret = read_sr(flash);

Maybe read_sr() and read_cr() shall be fixed to return retval only and the val 
shall be passed to them as an argument pointer? Aka. ret = read_sr(flash, &val);

That way, this dangerous construct below could become:

if (!(val & SR_....)) {
	dev_err();
	ret = -EINVAL;
}

return ret;

It will also let us prevent mixing of error codes and register values, which is 
pretty ugly practice.

> +	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
> +		dev_err(&flash->spi->dev,
> +			"Macronix Quad bit not set");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +

[...]

> +static inline int set_quad_mode(struct m25p *flash, u32 jedec_id)
> +{
> +	int status;
> +
> +	switch (JEDEC_MFR(jedec_id)) {
> +	case CFI_MFR_MACRONIX:
> +		status = macronix_quad_enable(flash);
> +		if (status) {
> +			dev_err(&flash->spi->dev,
> +				"Macronix quad not enable");

"Macronix quad-read not enabled" would be more sensible, DTTO below.

> +			return -EINVAL;
> +		}
> +		return status;
> +	default:
> +		status = spansion_quad_enable(flash);
> +		if (status) {
> +			dev_err(&flash->spi->dev,
> +				"Spansion quad not enable");
> +			return -EINVAL;
> +		}
> +		return status;
> +	}
> +}

[...]

> @@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
>  	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>  	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>  	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
> +	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },

I'm not convinced enabling 4-bit mode should be hard-coded in the MTD driver. 
There might be a board which uses this chip in 1-bit mode.

We have a setup with Spansion chip here which uses 1-bit addressing in U-Boot, 
but uses 4-bit addressing in Linux. We use a DT property to configure the SPI 
bus width for that and I think that's a way to go. Note that there also are 
chips which use 2-bit wide SPI communication.

[...]



From marex at denx.de  Sun Oct 27 12:45:59 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 17:45:59 +0100
Subject: [PATCH v2] mtd: m25p80: add support for Macronix mx25l3255e
In-Reply-To: <1382568003-2356-1-git-send-email-computersforpeace@gmail.com>
References: <1382568003-2356-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <201310271745.59262.marex@denx.de>

Dear Brian Norris,

> A new 32Mbit SPI NOR flash from Macronix. Nothing special.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> Cc: Marek Vasut <marex at denx.de>

Nothing special :)

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

> ---
> v2: correct "Gbit" to "MBit" in patch description
> 
>  drivers/mtd/devices/m25p80.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 8d6c87be..72c37f0 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -778,6 +778,7 @@ static const struct spi_device_id m25p_ids[] = {
>  	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
>  	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
>  	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
> +	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
>  	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
>  	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
>  	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },

Best regards,
Marek Vasut


From sourav.poddar at ti.com  Sun Oct 27 14:26:16 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Sun, 27 Oct 2013 23:56:16 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <201310271745.17152.marex@denx.de>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271745.17152.marex@denx.de>
Message-ID: <526D5AC8.2020703@ti.com>

Dear Marek,
On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> Dear Sourav Poddar,
>
> [...]
>
>> +static int macronix_quad_enable(struct m25p *flash)
>> +{
>> +	int ret, val;
>> +	u8 cmd[2];
>> +	cmd[0] = OPCODE_WRSR;
>> +
>> +	val = read_sr(flash);
>> +	cmd[1] = val | SR_QUAD_EN_MX;
>> +	write_enable(flash);
>> +
>> +	spi_write(flash->spi,&cmd, 2);
>> +
>> +	if (wait_till_ready(flash))
>> +		return 1;
>> +
>> +	ret = read_sr(flash);
> Maybe read_sr() and read_cr() shall be fixed to return retval only and the val
> shall be passed to them as an argument pointer? Aka. ret = read_sr(flash,&val);
>
> That way, this dangerous construct below could become:
>
> if (!(val&  SR_....)) {
> 	dev_err();
> 	ret = -EINVAL;
> }
>
> return ret;
>
> It will also let us prevent mixing of error codes and register values, which is
> pretty ugly practice.
>
ok. Will change.
>> +	if (!(ret>  0&&  (ret&  SR_QUAD_EN_MX))) {
>> +		dev_err(&flash->spi->dev,
>> +			"Macronix Quad bit not set");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
> [...]
>
>> +static inline int set_quad_mode(struct m25p *flash, u32 jedec_id)
>> +{
>> +	int status;
>> +
>> +	switch (JEDEC_MFR(jedec_id)) {
>> +	case CFI_MFR_MACRONIX:
>> +		status = macronix_quad_enable(flash);
>> +		if (status) {
>> +			dev_err(&flash->spi->dev,
>> +				"Macronix quad not enable");
> "Macronix quad-read not enabled" would be more sensible, DTTO below.
>
Ok. Will change.
>> +			return -EINVAL;
>> +		}
>> +		return status;
>> +	default:
>> +		status = spansion_quad_enable(flash);
>> +		if (status) {
>> +			dev_err(&flash->spi->dev,
>> +				"Spansion quad not enable");
>> +			return -EINVAL;
>> +		}
>> +		return status;
>> +	}
>> +}
> [...]
>
>> @@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
>>   	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>>   	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>>   	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
>> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
>> +	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
> I'm not convinced enabling 4-bit mode should be hard-coded in the MTD driver.
> There might be a board which uses this chip in 1-bit mode.
>
> We have a setup with Spansion chip here which uses 1-bit addressing in U-Boot,
> but uses 4-bit addressing in Linux. We use a DT property to configure the SPI
> bus width for that and I think that's a way to go. Note that there also are
> chips which use 2-bit wide SPI communication.
>
Yes, but if you trace down the patch below, you will see its not hard coded.
Enabling quad read mode depends on the following:

1. Whether flash chip supports it.
         This information comes from the flash which we are setting above.

2. Whether SPI controller supports it.
             This information is the check down below in the 
patch(spi->mode & SPI_RX_QUAD).
             spi->mode is set to "SINGLE/DUAL/QUAD" in the SPI framework 
based on the
            dt property "spi-tx/rx-bus-width".
So, unless you set spi->mode to SPI_RX_QUAD by setting 
"spi-rx-bus-width" to 4 in dt, default
will be 1 bit mode only.
> [...]
>



From marex at denx.de  Sun Oct 27 14:30:34 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 19:30:34 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526D5AC8.2020703@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271745.17152.marex@denx.de> <526D5AC8.2020703@ti.com>
Message-ID: <201310271930.34528.marex@denx.de>

Dear Sourav Poddar,

> Dear Marek,
> 
> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> > Dear Sourav Poddar,
> > 
> > [...]

[...]

> >> @@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
> >> 
> >>   	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
> >>   	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
> >>   	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
> >> 
> >> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
> >> +	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ)
> >> },
> > 
> > I'm not convinced enabling 4-bit mode should be hard-coded in the MTD
> > driver. There might be a board which uses this chip in 1-bit mode.
> > 
> > We have a setup with Spansion chip here which uses 1-bit addressing in
> > U-Boot, but uses 4-bit addressing in Linux. We use a DT property to
> > configure the SPI bus width for that and I think that's a way to go.
> > Note that there also are chips which use 2-bit wide SPI communication.
> 
> Yes, but if you trace down the patch below, you will see its not hard
> coded. Enabling quad read mode depends on the following:
> 
> 1. Whether flash chip supports it.
>          This information comes from the flash which we are setting above.
> 
> 2. Whether SPI controller supports it.
>              This information is the check down below in the
> patch(spi->mode & SPI_RX_QUAD).
>              spi->mode is set to "SINGLE/DUAL/QUAD" in the SPI framework
> based on the
>             dt property "spi-tx/rx-bus-width".
> So, unless you set spi->mode to SPI_RX_QUAD by setting
> "spi-rx-bus-width" to 4 in dt, default
> will be 1 bit mode only.

So this M25P80_QUAD_READ flag tells us "this chip supports quad read", not 
"force enable quad read" . All right, thanks for clearing this up. I hope it's 
documented somewhere elsewhere than in this email ;-)

Best regards,
Marek Vasut


From sourav.poddar at ti.com  Sun Oct 27 14:37:39 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Mon, 28 Oct 2013 00:07:39 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <201310271930.34528.marex@denx.de>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271745.17152.marex@denx.de> <526D5AC8.2020703@ti.com>
 <201310271930.34528.marex@denx.de>
Message-ID: <526D5D73.9060104@ti.com>

Dear Marek,
On Monday 28 October 2013 12:00 AM, Marek Vasut wrote:
> Dear Sourav Poddar,
>
>> Dear Marek,
>>
>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
>>> Dear Sourav Poddar,
>>>
>>> [...]
> [...]
>
>>>> @@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
>>>>
>>>>    	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>>>>    	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>>>>    	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
>>>>
>>>> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
>>>> +	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ)
>>>> },
>>> I'm not convinced enabling 4-bit mode should be hard-coded in the MTD
>>> driver. There might be a board which uses this chip in 1-bit mode.
>>>
>>> We have a setup with Spansion chip here which uses 1-bit addressing in
>>> U-Boot, but uses 4-bit addressing in Linux. We use a DT property to
>>> configure the SPI bus width for that and I think that's a way to go.
>>> Note that there also are chips which use 2-bit wide SPI communication.
>> Yes, but if you trace down the patch below, you will see its not hard
>> coded. Enabling quad read mode depends on the following:
>>
>> 1. Whether flash chip supports it.
>>           This information comes from the flash which we are setting above.
>>
>> 2. Whether SPI controller supports it.
>>               This information is the check down below in the
>> patch(spi->mode&  SPI_RX_QUAD).
>>               spi->mode is set to "SINGLE/DUAL/QUAD" in the SPI framework
>> based on the
>>              dt property "spi-tx/rx-bus-width".
>> So, unless you set spi->mode to SPI_RX_QUAD by setting
>> "spi-rx-bus-width" to 4 in dt, default
>> will be 1 bit mode only.
> So this M25P80_QUAD_READ flag tells us "this chip supports quad read", not
> "force enable quad read" .
Yes, correct.
> All right, thanks for clearing this up. I hope it's
> documented somewhere elsewhere than in this email ;-)
Its added as a comment under struct flash_info where
this flag is defined.
> Best regards,
> Marek Vasut



From marex at denx.de  Sun Oct 27 14:47:49 2013
From: marex at denx.de (Marek Vasut)
Date: Sun, 27 Oct 2013 19:47:49 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526D5D73.9060104@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271930.34528.marex@denx.de> <526D5D73.9060104@ti.com>
Message-ID: <201310271947.49904.marex@denx.de>

Dear Sourav Poddar,

> Dear Marek,
> 
> On Monday 28 October 2013 12:00 AM, Marek Vasut wrote:
> > Dear Sourav Poddar,
> > 
> >> Dear Marek,
> >> 
> >> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> >>> Dear Sourav Poddar,
> >>> 
> >>> [...]
> > 
> > [...]
> > 
> >>>> @@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
> >>>> 
> >>>>    	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
> >>>>    	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
> >>>>    	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
> >>>> 
> >>>> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
> >>>> +	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024,
> >>>> M25P80_QUAD_READ) },
> >>> 
> >>> I'm not convinced enabling 4-bit mode should be hard-coded in the MTD
> >>> driver. There might be a board which uses this chip in 1-bit mode.
> >>> 
> >>> We have a setup with Spansion chip here which uses 1-bit addressing in
> >>> U-Boot, but uses 4-bit addressing in Linux. We use a DT property to
> >>> configure the SPI bus width for that and I think that's a way to go.
> >>> Note that there also are chips which use 2-bit wide SPI communication.
> >> 
> >> Yes, but if you trace down the patch below, you will see its not hard
> >> coded. Enabling quad read mode depends on the following:
> >> 
> >> 1. Whether flash chip supports it.
> >> 
> >>           This information comes from the flash which we are setting
> >>           above.
> >> 
> >> 2. Whether SPI controller supports it.
> >> 
> >>               This information is the check down below in the
> >> 
> >> patch(spi->mode&  SPI_RX_QUAD).
> >> 
> >>               spi->mode is set to "SINGLE/DUAL/QUAD" in the SPI
> >>               framework
> >> 
> >> based on the
> >> 
> >>              dt property "spi-tx/rx-bus-width".
> >> 
> >> So, unless you set spi->mode to SPI_RX_QUAD by setting
> >> "spi-rx-bus-width" to 4 in dt, default
> >> will be 1 bit mode only.
> > 
> > So this M25P80_QUAD_READ flag tells us "this chip supports quad read",
> > not "force enable quad read" .
> 
> Yes, correct.
> 
> > All right, thanks for clearing this up. I hope it's
> > documented somewhere elsewhere than in this email ;-)
> 
> Its added as a comment under struct flash_info where
> this flag is defined.

Thank you!

Best regards,
Marek Vasut


From computersforpeace at gmail.com  Sun Oct 27 18:48:48 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Sun, 27 Oct 2013 15:48:48 -0700
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
In-Reply-To: <201310271730.12065.marex@denx.de>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <201310271730.12065.marex@denx.de>
Message-ID: <CAN8TOE-LWj7+6NRZbKJDz=fvVgMVtRvA5UqJ5AvLAwG+jRpgpw@mail.gmail.com>

On Sun, Oct 27, 2013 at 9:30 AM, Marek Vasut <marex at denx.de> wrote:
> Hi Brian,
>
> [...]
>
>> @@ -1137,14 +1135,10 @@ static int m25p_probe(struct spi_device *spi)
>>  static int m25p_remove(struct spi_device *spi)
>>  {
>>       struct m25p     *flash = spi_get_drvdata(spi);
>> -     int             status;
>>
>>       /* Clean up MTD stuff. */
>> -     status = mtd_device_unregister(&flash->mtd);
>> -     if (status == 0) {
>> -             kfree(flash->command);
>> -             kfree(flash);
>> -     }
>> +     mtd_device_unregister(&flash->mtd);
>> +
>>       return 0;
>>  }
>
> I wonder if we shouldn't return "status" in here in case mtd_device_unregister()
> failed.

Sure, I thought of that earlier actually. I may send a trivial
follow-up patch for this.

Thanks,
Brian


From ezequiel.garcia at free-electrons.com  Sun Oct 27 20:51:45 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 27 Oct 2013 21:51:45 -0300
Subject: [PATCH 0/3] omap2: Assorted GPMC cleanups
Message-ID: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>

(I'm CCing the MTD list, because GPMC is the memory controller
used for NOR, NAND and OneNAND devices).

Hi all,

Just a small patchset containing two small cleanups and a minor fix
for the GPMC memory controller. The first two are cleanups and can
be considered as preparation work for the fix.

The fix is patch 3/3: "Move legacy GPMC width setting". It makes
explicit use of the DT property "gpmc,device-width" and removes the
subsequent (and redundant) setting of the GPMC width, based in the
NAND bus widht.

Tested in AM335x (using DT) so I'd appreciate if someone can test using
a board-file, on a device with NAND flash.

Jon: If you happen to read this, I'd like if you could take a look at
patch 1/3, since you were the last to touch that part of the code.

Thanks!

Ezequiel Garcia (3):
  omap2: gpmc: Move initialization outside the gpmc_t condition
  omap2: gpmc: Introduce gpmc_set_legacy()
  omap2: gpmc: Move legacy GPMC width setting

 arch/arm/mach-omap2/gpmc-nand.c | 50 +++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Sun Oct 27 20:51:47 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 27 Oct 2013 21:51:47 -0300
Subject: [PATCH 2/3] omap2: gpmc: Introduce gpmc_set_legacy()
In-Reply-To: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382921508-5104-3-git-send-email-ezequiel.garcia@free-electrons.com>

Introduce a helper function to complete the setting of some GPMC
parameters, only used when the gpmc is probed from a board file.
As such, it will go away once the DT conversion is completed.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/mach-omap2/gpmc-nand.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index d66b856..9dd40e7 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -65,6 +65,17 @@ static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
 	return 1;
 }
 
+/* This function will go away once the device-tree convertion is complete */
+static void gpmc_set_legacy(struct omap_nand_platform_data *gpmc_nand_data,
+			    struct gpmc_settings *s)
+{
+	/* Enable RD PIN Monitoring Reg */
+	if (gpmc_nand_data->dev_ready) {
+		s->wait_on_read = true;
+		s->wait_on_write = true;
+	}
+}
+
 int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 		   struct gpmc_timings *gpmc_t)
 {
@@ -100,15 +111,10 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 		}
 	}
 
-	if (gpmc_nand_data->of_node) {
+	if (gpmc_nand_data->of_node)
 		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
-	} else {
-		/* Enable RD PIN Monitoring Reg */
-		if (gpmc_nand_data->dev_ready) {
-			s.wait_on_read = true;
-			s.wait_on_write = true;
-		}
-	}
+	else
+		gpmc_set_legacy(gpmc_nand_data, &s);
 
 	s.device_nand = true;
 
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Sun Oct 27 20:51:48 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 27 Oct 2013 21:51:48 -0300
Subject: [PATCH 3/3] omap2: gpmc: Move legacy GPMC width setting
In-Reply-To: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382921508-5104-4-git-send-email-ezequiel.garcia@free-electrons.com>

After the introduction of gpmc_set_legacy(), move the GPMC width setting
to be done inside it. Currently, in the DT probed case, this is (wrongly)
done twice: first at gpmc_read_settings_dt(), and then based in the
NAND width setting.
Fix this and use only the value obtained from the DT.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/mach-omap2/gpmc-nand.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 9dd40e7..174caec 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -74,6 +74,11 @@ static void gpmc_set_legacy(struct omap_nand_platform_data *gpmc_nand_data,
 		s->wait_on_read = true;
 		s->wait_on_write = true;
 	}
+
+	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+		s->device_width = GPMC_DEVWIDTH_16BIT;
+	else
+		s->device_width = GPMC_DEVWIDTH_8BIT;
 }
 
 int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
@@ -118,11 +123,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 
 	s.device_nand = true;
 
-	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
-		s.device_width = GPMC_DEVWIDTH_16BIT;
-	else
-		s.device_width = GPMC_DEVWIDTH_8BIT;
-
 	err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
 	if (err < 0)
 		goto out_free_cs;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Sun Oct 27 20:51:46 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Sun, 27 Oct 2013 21:51:46 -0300
Subject: [PATCH 1/3] omap2: gpmc: Move initialization outside the gpmc_t
 condition
In-Reply-To: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382921508-5104-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1382921508-5104-2-git-send-email-ezequiel.garcia@free-electrons.com>

This commit moves a bunch of initialization previously enclosed
under a 'if (gpmc_t)' check, to be outside such condition.

These initializations are not related to gpmc_t (timings) in any way
so it's nonsense to enclose them under such check.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 arch/arm/mach-omap2/gpmc-nand.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 662c7fd..d66b856 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -98,32 +98,32 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 			dev_err(dev, "Unable to set gpmc timings: %d\n", err);
 			return err;
 		}
+	}
 
-		if (gpmc_nand_data->of_node) {
-			gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
-		} else {
-			/* Enable RD PIN Monitoring Reg */
-			if (gpmc_nand_data->dev_ready) {
-				s.wait_on_read = true;
-				s.wait_on_write = true;
-			}
+	if (gpmc_nand_data->of_node) {
+		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
+	} else {
+		/* Enable RD PIN Monitoring Reg */
+		if (gpmc_nand_data->dev_ready) {
+			s.wait_on_read = true;
+			s.wait_on_write = true;
 		}
+	}
 
-		s.device_nand = true;
+	s.device_nand = true;
 
-		if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
-			s.device_width = GPMC_DEVWIDTH_16BIT;
-		else
-			s.device_width = GPMC_DEVWIDTH_8BIT;
+	if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
+		s.device_width = GPMC_DEVWIDTH_16BIT;
+	else
+		s.device_width = GPMC_DEVWIDTH_8BIT;
 
-		err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
-		if (err < 0)
-			goto out_free_cs;
+	err = gpmc_cs_program_settings(gpmc_nand_data->cs, &s);
+	if (err < 0)
+		goto out_free_cs;
 
-		err = gpmc_configure(GPMC_CONFIG_WP, 0);
-		if (err < 0)
-			goto out_free_cs;
-	}
+	err = gpmc_configure(GPMC_CONFIG_WP, 0);
+	if (err < 0)
+		goto out_free_cs;
 
 	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
 
-- 
1.8.1.5



From florian at openwrt.org  Sun Oct 27 21:38:12 2013
From: florian at openwrt.org (Florian Fainelli)
Date: Sun, 27 Oct 2013 18:38:12 -0700
Subject: Patching mkfs.ubifs.c for running under Windows ?
In-Reply-To: <1382782672.5901.25.camel@karhu.quadriga.com>
References: <mailman.6.1379692801.23497.linux-mtd@lists.infradead.org>
 <7c74c0d714e8e87daebbfd0163642d71@localhost>
 <1382782672.5901.25.camel@karhu.quadriga.com>
Message-ID: <CAGVrzcY7RD0AFvkPLvoCSe5iFFtwXnLthVepJ=XrR4bhMPN6_A@mail.gmail.com>

Hello,

2013/10/26 Artem Bityutskiy <dedekind1 at gmail.com>:
> On Sat, 2013-09-21 at 12:58 +0200, gutemine wrote:
>> As users of ubidump under Windows now asked me for getting also the
>> possibility to re-pack their extracted ubifs images, I'm considering to
>> patch mkfs.ubifs.c, so that it handles also the Windows hard and softlinks
>> and my dummy device files correctly.
>
> Generally, I am OK with making the code support windows, why not? But
> this should be done very nicely and should not be intrusive. I guess you
> should send patches and then we'll see.

We do have some patches in OpenWrt to make mtd-utils build and work
under FreeBSD and Cygwin here:

https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches

in particular:
https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/110-portability.patch
https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/120-cygwin_fixes.patch
https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/134-freebsd_loff_t.patch

Not sure how acceptable they look like to you?
-- 
Florian


From b32955 at freescale.com  Sun Oct 27 22:57:33 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 28 Oct 2013 10:57:33 +0800
Subject: [PATCH] ubi: attach: do not return -EINVAL if the
 mtd->numeraseregions is 1
In-Reply-To: <1382780870.5901.20.camel@karhu.quadriga.com>
References: <1379470659-12158-1-git-send-email-b32955@freescale.com>
 <1382780870.5901.20.camel@karhu.quadriga.com>
Message-ID: <526DD29D.2070407@freescale.com>

? 2013?10?26? 17:47, Artem Bityutskiy ??:
> What is 'numeraseregions == 1'? How is it different to 'numeraseregions
> == 0'?
>
> Is the "main" area covered by mtd->size, or 'mtd->size' spans the entire
> chip and includes all the regions?
>
i think the mtd->size spans the entire chip and include the all the regions.


> What is the flash you are dealing with? Surely this is not gpmi-nand?
I meet this bug with a Micron's Parallel Nor: M29W256GL
it is not used by the gpmi-nand, it's used by weim driver: 
drivers/bus/imx-weim.c

this NOR's Number of erase block regions is 1, i quote the test here, 
see page 50
(i will send you the datasheet in a private email):

"
   It specifes the number of regions containning contiguous erase blocks 
of the same size.

"

please see allocate_partition():

   
---------------------------------------------------------------------------------
   if (master->numeraseregions > 1) {
       ................
   } else {
       /* Single erase size */
   }

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

this NOR is 32MB, its master partion has 1 for "numeraseregions". if we 
add a 32MB slave partition
  to this NOR, the slave partition does NOT inherit the numeraseregions 
of the master partition.
So the ubiattach will succeed with the slave partition.

But if we attach the master partition directly, we will fails.

thanks
Huang Shijie








From b32955 at freescale.com  Sun Oct 27 23:05:17 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Mon, 28 Oct 2013 11:05:17 +0800
Subject: [PATCH v2] mtd: gpmi: add a new DT property to use the datasheet's
 minimum required ECC
Message-ID: <1382929517-22606-1-git-send-email-b32955@freescale.com>

In default way, we use the ecc_strength/ecc_step size calculated by ourselves
and use all the OOB area.

This patch adds a new property : "fsl,use-minimum-ecc"

If we enable it, we will firstly try to use the datasheet's minimum required
ECC provided by the MTD layer (the ecc_strength_ds/ecc_step_ds fields
in the nand_chip{}). So we may have free space in the OOB area by using the
minimum ECC, and we may support JFFS2 with some SLC NANDs, such as Micron's
SLC NAND.

If we fail to use the minimum ECC, we will use the legacy method to calculate
the ecc_strength and ecc_step size.

Signed-off-by: Huang Shijie <b32955 at freescale.com>
---
v1 --> v2:
	based on David's patch to fix the regression.
---
 .../devicetree/bindings/mtd/gpmi-nand.txt          |    6 ++++++
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c             |    3 +++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index 551b2a1..4297795 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -17,6 +17,12 @@ Required properties:
 Optional properties:
   - nand-on-flash-bbt: boolean to enable on flash bbt option if not
                        present false
+  - fsl,use-minimum-ecc: By enabling this boolean property, the gpmi will try
+                       to use the datasheet's minimum required ECC provided by
+                       the MTD layer (the ecc_strength_ds/ecc_step_ds fields
+                       in the nand_chip{}). So we may have free space in the OOB
+                       area by using the minimum ECC, and we may support JFFS2
+                       with some SLC NANDs, such as Micron's SLC NAND.
 
 The device tree may optionally contain sub-nodes describing partitions of the
 address space. See partition.txt for more detail.
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 7ac2280..3ec55d0 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -352,6 +352,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this)
 
 int common_nfc_set_geometry(struct gpmi_nand_data *this)
 {
+	if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")
+		&& set_geometry_by_ecc_info(this))
+		return 0;
 	return legacy_set_geometry(this);
 }
 
-- 
1.7.2.rc3




From qiwang at micron.com  Mon Oct 28 00:49:11 2013
From: qiwang at micron.com (=?utf-8?B?UWkgV2FuZyDnjovotbcgKHFpd2FuZyk=?=)
Date: Mon, 28 Oct 2013 04:49:11 +0000
Subject: [PATCH 1/1]  MTD: UBI:  try to avoid program data to NOR flash
 after erasure interrupted
In-Reply-To: <1382779164.5901.1.camel@karhu.quadriga.com>
References: <71CF8D7F32C5C24C9CD1D0E02D52498A77082AC5@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A77082DDB@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED11@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED44@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED67@NTXXIAMBX02.xacn.micron.com>
 <1382779164.5901.1.camel@karhu.quadriga.com>
Message-ID: <71CF8D7F32C5C24C9CD1D0E02D52498A770B1B87@NTXXIAMBX02.xacn.micron.com>

On Sa, 2013-10-26 at 05:19 +0000, Artem Bityutskiy wrote:
>On Thu, 2013-10-10 at 08:28 +0000, Qi Wang ?? (qiwang) wrote:
>> But I want to say the potential risk is if low level driver program data to 
>> this block, it will get ?timeout error?. And the timeout period could be very 
>> long(almost several minutes), during this period, any operation on NOR flash 
>> cannot be accept. so program data to a erasure interrupted block isn?t a 
>> sensible action. in order to avoid program a erasure interrupted block, 
>> I suggest UBIFS can read this block before program data. the code changing as below:
>
>Yes, reading first sounds like a good idea. Would you please send a
>patch implementing it?

From: Qi Wang <qiwang at micron.com>

nor_erase_prepare() will be called before erase a NOR flash, it will program '0'
into a block to mark this block. But program data into a erasure interrupted block
can cause program timtout(several minutes at most) error, could impact other 
operation on NOR flash. So UBIFS can read this block first to avoid unneeded 
program operation. 

This patch try to put read operation at at head of write operation in 
nor_erase_prepare(), read out the data. 
If the data is already corrupt, then no need to program any data into this block, 
just go to erase this block.

Signed-off-by: Qi Wang <qiwang at qiwang@micron.com>
---
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index bf79def..be6ab56 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -509,26 +509,10 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 	struct ubi_vid_hdr vid_hdr;
 
 	/*
-	 * It is important to first invalidate the EC header, and then the VID
-	 * header. Otherwise a power cut may lead to valid EC header and
-	 * invalid VID header, in which case UBI will treat this PEB as
-	 * corrupted and will try to preserve it, and print scary warnings.
-	 */
-	addr = (loff_t)pnum * ubi->peb_size;
-	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
-	if (!err) {
-		addr += ubi->vid_hdr_aloffset;
-		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
-		if (!err)
-			return 0;
-	}
-
-	/*
-	 * We failed to write to the media. This was observed with Spansion
-	 * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+	 * Most probably the previously eraseblock erasure
 	 * was interrupted at a very inappropriate moment, so it became
-	 * unwritable. In this case we probably anyway have garbage in this
-	 * PEB.
+	 * unwritable. In order to avoid program data into a unwritable block,
+	 * read this block first, and check if do need to program it.  
 	 */
 	err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
 	if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
@@ -547,6 +531,22 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 	}
 
 	/*
+	 * VID or EC is valid, need to corrupt these header before erase operation.  
+	 * It is important to first invalidate the EC header, and then the VID
+	 * header. Otherwise a power cut may lead to valid EC header and
+	 * invalid VID header, in which case UBI will treat this PEB as
+	 * corrupted and will try to preserve it, and print scary warnings.
+	 */
+	addr = (loff_t)pnum * ubi->peb_size;
+	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+	if (!err) {
+		addr += ubi->vid_hdr_aloffset;
+		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+		if (!err)
+			return 0;
+	}
+
+	/*
 	 * The PEB contains a valid VID header, but we cannot invalidate it.
 	 * Supposedly the flash media or the driver is screwed up, so return an
 	 * error.
---


From qiwang at micron.com  Mon Oct 28 00:54:36 2013
From: qiwang at micron.com (=?utf-8?B?UWkgV2FuZyDnjovotbcgKHFpd2FuZyk=?=)
Date: Mon, 28 Oct 2013 04:54:36 +0000
Subject: [PATCH 1/1]  MTD: UBI:  try to avoid program data to NOR flash
 after erasure interrupted
References: <71CF8D7F32C5C24C9CD1D0E02D52498A77082AC5@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A77082DDB@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED11@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED44@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED67@NTXXIAMBX02.xacn.micron.com>
 <1382779164.5901.1.camel@karhu.quadriga.com> 
Message-ID: <71CF8D7F32C5C24C9CD1D0E02D52498A770B1B97@NTXXIAMBX02.xacn.micron.com>

On Sa, 2013-10-26 at 05:19 +0000, Artem Bityutskiy wrote:
>On Thu, 2013-10-10 at 08:28 +0000, Qi Wang ?? (qiwang) wrote:
>> But I want to say the potential risk is if low level driver program data to 
>> this block, it will get ?timeout error?. And the timeout period could be very 
>> long(almost several minutes), during this period, any operation on NOR flash 
>> cannot be accept. so program data to a erasure interrupted block isn?t a 
>> sensible action. in order to avoid program a erasure interrupted block, 
>> I suggest UBIFS can read this block before program data. the code changing as below:
>
>Yes, reading first sounds like a good idea. Would you please send a
>patch implementing it?

From: Qi Wang <qiwang at micron.com>

nor_erase_prepare() will be called before erase a NOR flash, it will program '0'
into a block to mark this block. But program data into a erasure interrupted block
can cause program timtout(several minutes at most) error, could impact other 
operation on NOR flash. So UBIFS can read this block first to avoid unneeded 
program operation. 

This patch try to put read operation at at head of write operation in 
nor_erase_prepare(), read out the data. 
If the data is already corrupt, then no need to program any data into this block, 
just go to erase this block.

Signed-off-by: Qi Wang <qiwang at qiwang@micron.com>
---
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index bf79def..be6ab56 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -509,26 +509,10 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 	struct ubi_vid_hdr vid_hdr;
 
 	/*
-	 * It is important to first invalidate the EC header, and then the VID
-	 * header. Otherwise a power cut may lead to valid EC header and
-	 * invalid VID header, in which case UBI will treat this PEB as
-	 * corrupted and will try to preserve it, and print scary warnings.
-	 */
-	addr = (loff_t)pnum * ubi->peb_size;
-	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
-	if (!err) {
-		addr += ubi->vid_hdr_aloffset;
-		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
-		if (!err)
-			return 0;
-	}
-
-	/*
-	 * We failed to write to the media. This was observed with Spansion
-	 * S29GL512N NOR flash. Most probably the previously eraseblock erasure
+	 * Most probably the previously eraseblock erasure
 	 * was interrupted at a very inappropriate moment, so it became
-	 * unwritable. In this case we probably anyway have garbage in this
-	 * PEB.
+	 * unwritable. In order to avoid program data into a unwritable block,
+	 * read this block first, and check if do need to program it.  
 	 */
 	err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
 	if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
@@ -547,6 +531,22 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 	}
 
 	/*
+	 * VID or EC is valid, need to corrupt these header before erase operation.  
+	 * It is important to first invalidate the EC header, and then the VID
+	 * header. Otherwise a power cut may lead to valid EC header and
+	 * invalid VID header, in which case UBI will treat this PEB as
+	 * corrupted and will try to preserve it, and print scary warnings.
+	 */
+	addr = (loff_t)pnum * ubi->peb_size;
+	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+	if (!err) {
+		addr += ubi->vid_hdr_aloffset;
+		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+		if (!err)
+			return 0;
+	}
+
+	/*
 	 * The PEB contains a valid VID header, but we cannot invalidate it.
 	 * Supposedly the flash media or the driver is screwed up, so return an
 	 * error.
---


From marex at denx.de  Mon Oct 28 03:54:15 2013
From: marex at denx.de (Marek Vasut)
Date: Mon, 28 Oct 2013 08:54:15 +0100
Subject: [PATCH 1/5] mtd: m25p80: fix allocation size
In-Reply-To: <CAN8TOE-LWj7+6NRZbKJDz=fvVgMVtRvA5UqJ5AvLAwG+jRpgpw@mail.gmail.com>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <201310271730.12065.marex@denx.de>
 <CAN8TOE-LWj7+6NRZbKJDz=fvVgMVtRvA5UqJ5AvLAwG+jRpgpw@mail.gmail.com>
Message-ID: <201310280854.15268.marex@denx.de>

Hi Brian,

> On Sun, Oct 27, 2013 at 9:30 AM, Marek Vasut <marex at denx.de> wrote:
> > Hi Brian,
> > 
> > [...]
> > 
> >> @@ -1137,14 +1135,10 @@ static int m25p_probe(struct spi_device *spi)
> >> 
> >>  static int m25p_remove(struct spi_device *spi)
> >>  {
> >>  
> >>       struct m25p     *flash = spi_get_drvdata(spi);
> >> 
> >> -     int             status;
> >> 
> >>       /* Clean up MTD stuff. */
> >> 
> >> -     status = mtd_device_unregister(&flash->mtd);
> >> -     if (status == 0) {
> >> -             kfree(flash->command);
> >> -             kfree(flash);
> >> -     }
> >> +     mtd_device_unregister(&flash->mtd);
> >> +
> >> 
> >>       return 0;
> >>  
> >>  }
> > 
> > I wonder if we shouldn't return "status" in here in case
> > mtd_device_unregister() failed.
> 
> Sure, I thought of that earlier actually. I may send a trivial
> follow-up patch for this.

Sounds good, certainly better than mixing two things into one patch. Thanks!

Best regards,
Marek Vasut


From richard.weinberger at gmail.com  Mon Oct 28 06:47:06 2013
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Mon, 28 Oct 2013 11:47:06 +0100
Subject: Patching mkfs.ubifs.c for running under Windows ?
In-Reply-To: <CAGVrzcY7RD0AFvkPLvoCSe5iFFtwXnLthVepJ=XrR4bhMPN6_A@mail.gmail.com>
References: <mailman.6.1379692801.23497.linux-mtd@lists.infradead.org>
 <7c74c0d714e8e87daebbfd0163642d71@localhost>
 <1382782672.5901.25.camel@karhu.quadriga.com>
 <CAGVrzcY7RD0AFvkPLvoCSe5iFFtwXnLthVepJ=XrR4bhMPN6_A@mail.gmail.com>
Message-ID: <CAFLxGvyt2w31v7v1cmvKBE6=hLkY1G-v31srsoQz82ktxg7SAg@mail.gmail.com>

On Mon, Oct 28, 2013 at 2:38 AM, Florian Fainelli <florian at openwrt.org> wrote:
> Hello,
>
> 2013/10/26 Artem Bityutskiy <dedekind1 at gmail.com>:
>> On Sat, 2013-09-21 at 12:58 +0200, gutemine wrote:
>>> As users of ubidump under Windows now asked me for getting also the
>>> possibility to re-pack their extracted ubifs images, I'm considering to
>>> patch mkfs.ubifs.c, so that it handles also the Windows hard and softlinks
>>> and my dummy device files correctly.
>>
>> Generally, I am OK with making the code support windows, why not? But
>> this should be done very nicely and should not be intrusive. I guess you
>> should send patches and then we'll see.
>
> We do have some patches in OpenWrt to make mtd-utils build and work
> under FreeBSD and Cygwin here:
>
> https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches
>
> in particular:
> https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/110-portability.patch
> https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/120-cygwin_fixes.patch
> https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/134-freebsd_loff_t.patch
>
> Not sure how acceptable they look like to you?

Looks not that bad. :-)
But why do you need the file "include/cygwin/bits-byteswap.h"?

Artem, what do you think?
IMHO adding cygwin support is less intrusive than adding native win32 support.

-- 
Thanks,
//richard


From andrea.adami at gmail.com  Mon Oct 28 07:17:02 2013
From: andrea.adami at gmail.com (Andrea Adami)
Date: Mon, 28 Oct 2013 12:17:02 +0100
Subject: Issues unlocking LH28F640BF NOR flash
Message-ID: <CAAQYJAtGEVUY98Z1gthPbYCMG_A8yWC-d+c-bJeGWUhTF0WbVw@mail.gmail.com>

Hi all,

I'm trying to fixup the flash on the Zaurus SL-5500 that is locked on boot.

The 2 chips are 4Mbix16 LH28F640BFHE-PTTL90 on a 32 bit wide bus
(sa1100) and they appear interleaved: D0-D15 on one chip and D16-D31
on the other.
The specifics don't even mention an 8bit mode. See [1] and [2].
Primary command set (16bit Vendor ID 0003H) so it is Sharp, detected
as Intel P_ID_INTEL_STD even if it seems explicitely Extended...the
Sharp-specific extended query is: major 1  minor  3

With jedec_probe they are detected as expected with interleave of 2
and buswidth of 32bit, see logs [3].

I need to boot from flash so all the drivers are compiled in kernel.
Now the issue is that from userspace flash_unlock /dev/mtd2 stalls and
doesn't finish.
>From the kernel side, I've managed to add a fixup for this Sharp chip
(standard fixup is only for CFI_MFR_INTEL /Strataflash) to
jedec_fixup_table and to countertest I've even hacked
uapi/mtd/mtd-abi.h and added MTD_POWERUP_LOCK to MTD_CAP_NORFLASH.

Strangely all is fine when the cfi/jedec drivers and the sa1100 map
are compiled as modules,  otherwise the kernel won't finish boot (as
from userspace).

How can that happen?

Thanks in advance for your help

Andrea

P.S.
Once done I'll try to see why CFI detection fails on gen_probe:
gen_probe:genprobe_ident_chips: CFI: Found no sa1100-0 device at location zero

[1] Datasheet v. 2.41
http://www.datasheetarchive.com/dlmain/Datasheets-314/276727.pdf

[2] Appendix v. 2.44
http://www.datasheetarchive.com/dl/Datasheet-019/DSA00340384.pdf

[3]
root at collie:~# depmod -a
root at collie:~# modprobe cfi_util dyndbg==pmf
root at collie:~# modprobe cfi_cmdset_0001 dyndbg==pmf
root at collie:~# modprobe gen_probe dyndbg==pmf
root at collie:~# modprobe cfi_probe dyndbg==pmf
root at collie:~# modprobe jedec_probe dyndbg==pmf
root at collie:~# modprobe sa1100_flash dyndbg==pmf
jedec_probe:jedec_reset: reset unlock called 555 2aa
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_reset: reset unlock called 555 aaa
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_reset: reset unlock called 5555 2aaa
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_reset: reset unlock called aaa 554
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_reset: reset unlock called aaa 555
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_reset: reset unlock called aaaa 5555
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(4) type(1)
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_match: jedec_match(): ID is not 8bit
jedec_probe:jedec_reset: reset unlock called 2aa 155
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_reset: reset unlock called 2aa 555
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_reset: reset unlock called 2aaa 1555
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_reset: reset unlock called 555 2aa
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_reset: reset unlock called 555 2aa
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_reset: reset unlock called 5555 2aaa
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_probe_chip: Search for id:(b0 01) interleave(4) type(2)
jedec_probe:jedec_reset: reset unlock called 155 aa
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_reset: reset unlock called 155 2aa
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_reset: reset unlock called 1555 aaa
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_reset: reset unlock called 2aa 155
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_reset: reset unlock called 2aa 155
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_reset: reset unlock called 2aaa 1555
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_probe_chip: Search for id:(b000b0 00) interleave(4) type(4)
jedec_probe:jedec_reset: reset unlock called 2aa 155
jedec_probe:jedec_probe_chip: Search for id:(b0 b0) interleave(2) type(2)
jedec_probe:jedec_match: MTD jedec_match(): Check fit 0x00000000 +
0x00800000 = 0x00800000
jedec_probe:jedec_match: MTD jedec_match(): check unlock addrs 0x02aa 0x0155
jedec_probe:jedec_match: MTD jedec_match(): check ID's disappear when
not in ID mode
jedec_probe:jedec_reset: reset unlock called 2aa 155
jedec_probe:jedec_match: MTD jedec_match(): return to ID mode
jedec_probe:jedec_probe_chip: MTD jedec_probe_chip(): matched device
0xb0,0xb0 unlock_addrs: 0x02aa 0x0155
Found: LH28F640BF
sa1100-0: Found 2 x16 devices at 0x0 in 32-bit bank
sa1100-0: Found different chip or no chip at all (mfr 0x4, id 0x3001)
at 0x1000000
erase region 0: offset=0x0,size=0x20000,blocks=127
erase region 1: offset=0xfe0000,size=0x4000,blocks=8
SA1100 flash: CFI device at 0x00000000, 16MiB, 32-bit
Creating 3 MTD partitions on "sa1100":
0x000000000000-0x0000000c0000 : "bootloader"
0x0000000c0000-0x0000001c0000 : "kernel"
0x0000001c0000-0x000000fe0000 : "rootfs"
root at collie:~#


From vladimir_zapolskiy at mentor.com  Mon Oct 28 12:08:15 2013
From: vladimir_zapolskiy at mentor.com (Vladimir Zapolskiy)
Date: Mon, 28 Oct 2013 18:08:15 +0200
Subject: [PATCH] mtd: mtdchar: return expected errors on mmap() call
Message-ID: <1382976495-1250-1-git-send-email-vladimir_zapolskiy@mentor.com>

According both to POSIX.1-2008 and Linux Programmer's Manual mmap()
syscall shouldn't return undocumented ENOSYS, this change replaces
the errno with more appropriate ENODEV and EACCESS.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy at mentor.com>
Cc: David Woodhouse <David.Woodhouse at intel.com>
---
 drivers/mtd/mtdchar.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 684bfa3..a4c026e 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1099,7 +1099,7 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file,
 		return (unsigned long) -EINVAL;
 
 	ret = mtd_get_unmapped_area(mtd, len, offset, flags);
-	return ret == -EOPNOTSUPP ? -ENOSYS : ret;
+	return ret == -EOPNOTSUPP ? -ENODEV : ret;
 }
 #endif
 
@@ -1124,9 +1124,9 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
 #endif
 		return vm_iomap_memory(vma, map->phys, map->size);
 	}
-	return -ENOSYS;
+	return -ENODEV;
 #else
-	return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
+	return vma->vm_flags & VM_SHARED ? 0 : -EACCES;
 #endif
 }
 
-- 
1.7.10.4



From annulen at yandex.ru  Mon Oct 28 12:22:38 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Mon, 28 Oct 2013 20:22:38 +0400
Subject: lz4hc compression in UBIFS?
In-Reply-To: <106621382627723@web13g.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <loom.20131023T201657-894@post.gmane.org> <237221382623942@web21m.yandex.ru>
 <106621382627723@web13g.yandex.ru>
Message-ID: <3901382977358@web14h.yandex.ru>



24.10.2013, 19:15, "Konstantin Tokarev" <annulen at yandex.ru>:
> Attached patch to crypto API wrapper for lz4hc seems to fix the issue. I can save
> and read files on LZ4HC-compressed volume, and I'm running on LZ4HC-compressed rootfs,
> flashed from mkfs.ubifs generated image (patch by Elie De Brauwer). My software
> works correctly.
>
> Unfortunately, on my board LZ4HC-compressed UBIFS volume performs noticeable worse
> than LZO, while still faster than zlib. I guess the reason is that CPU is no longer a
> bottleneck for my system, but NAND speed.
>
> Thank you all for your help!

Can anyone review the correctness of my patch? Looks like API of LZ4 decompressor is
used wrong way in crypto API.

-- 
Regards,
Konstantin


From f.fainelli at gmail.com  Mon Oct 28 12:45:23 2013
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 28 Oct 2013 09:45:23 -0700
Subject: lz4hc compression in UBIFS?
In-Reply-To: <3901382977358@web14h.yandex.ru>
References: <55541379679397@web20h.yandex.ru>
 <CAP+RiCAVuUEfyjg02+ZjeFXgUuaRW+fuMB490Ce2Hq_4qHBL=A@mail.gmail.com>
 <loom.20131023T201657-894@post.gmane.org> <237221382623942@web21m.yandex.ru>
 <106621382627723@web13g.yandex.ru> <3901382977358@web14h.yandex.ru>
Message-ID: <CAGVrzcYj91m=rC5ye9eAo=eMN0mBzk9-Bv8K6myTpnH28PLUxQ@mail.gmail.com>

2013/10/28 Konstantin Tokarev <annulen at yandex.ru>:
>
>
> 24.10.2013, 19:15, "Konstantin Tokarev" <annulen at yandex.ru>:
>> Attached patch to crypto API wrapper for lz4hc seems to fix the issue. I can save
>> and read files on LZ4HC-compressed volume, and I'm running on LZ4HC-compressed rootfs,
>> flashed from mkfs.ubifs generated image (patch by Elie De Brauwer). My software
>> works correctly.
>>
>> Unfortunately, on my board LZ4HC-compressed UBIFS volume performs noticeable worse
>> than LZO, while still faster than zlib. I guess the reason is that CPU is no longer a
>> bottleneck for my system, but NAND speed.
>>
>> Thank you all for your help!
>
> Can anyone review the correctness of my patch? Looks like API of LZ4 decompressor is
> used wrong way in crypto API.

Can you make a formal submission of it? That would probably help reviewing it.
--
Florian


From dorijan at kset.org  Mon Oct 28 17:56:54 2013
From: dorijan at kset.org (superpacsthet)
Date: Mon, 28 Oct 2013 22:56:54 +0100
Subject: =?iso-8859-5?Q?=B7=D4=E0=D0=D2=E1=E2=D2=E3=D9=E2=D5?=
Message-ID: <D2F17A35F4A84A2BA7D38EFD6A1E9475@uavzfph>

????????? ??????? ?????? ?????????? ????????? - ??????????? ?? ????. ???????? ??? ????????? ??? ?? ???????????. ???????????? ????????? ??????. ????????? ???? ???????. ?????????? ?????????, ??????????? ??????. ????? ???????? ???: http://www.blackdevil.weboldala.net/modules/mod_backup2/cwvsb.htm .


From laurent.pinchart+renesas at ideasonboard.com  Mon Oct 28 19:46:48 2013
From: laurent.pinchart+renesas at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 00:46:48 +0100
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
Message-ID: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

Hello,

This patch series, based on v3.12-rc7, prepares various Renesas drivers
for migration to multiplatform kernels by enabling their compilation or
otherwise fixing them on all ARM platforms. The patches are pretty
straightforward and are described in their commit message.

I'd like to get all these patches merged in v3.14. As they will need to go
through their respective subsystems' trees, I would appreciate if all
maintainers involved could notify me when they merge patches from this series
in their tree to help me tracking the merge status. I don't plan to send pull
requests individually for these patches, and I will repost patches
individually if changes are requested during review.

If you believe the issue should be solved in a different way (for instance by
removing the architecture dependency completely) please reply to the cover
letter to let other maintainers chime in.

Cc: Chris Ball <cjb at laptop.org>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: dmaengine at vger.kernel.org
Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Cc: Eduardo Valentin <eduardo.valentin at ti.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Guennadi Liakhovetski <g.liakhovetski+renesas at gmail.com>
Cc: Ian Molton <ian at mnementh.co.uk>
Cc: iommu at lists.linux-foundation.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Cc: Joerg Roedel <joro at 8bytes.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: linux-fbdev at vger.kernel.org
Cc: linux-i2c at vger.kernel.org
Cc: linux-input at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: linux-mmc at vger.kernel.org
Cc: linux-mtd at lists.infradead.org
Cc: linux-pm at vger.kernel.org
Cc: linux-pwm at vger.kernel.org
Cc: linux-serial at vger.kernel.org
Cc: linux-spi at vger.kernel.org
Cc: Magnus Damm <magnus.damm at gmail.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Mauro Carvalho Chehab <m.chehab at samsung.com>
Cc: netdev at vger.kernel.org
Cc: Samuel Ortiz <samuel at sortiz.org>
Cc: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
Cc: Vinod Koul <vinod.koul at intel.com>
Cc: Wolfram Sang <wsa at the-dreams.de>
Cc: Zhang Rui <rui.zhang at intel.com>

Laurent Pinchart (19):
  serial: sh-sci: Enable the driver on all ARM platforms
  DMA: shdma: Enable the driver on all ARM platforms
  i2c: sh_mobile: Enable the driver on all ARM platforms
  input: sh_keysc: Enable the driver on all ARM platforms
  iommu: shmobile: Enable the driver on all ARM platforms
  i2c: rcar: Enable the driver on all ARM platforms
  v4l: sh_vou: Enable the driver on all ARM platforms
  mmc: sdhi: Enable the driver on all ARM platforms
  mmc: sh_mmcif: Enable the driver on all ARM platforms
  mtd: sh_flctl: Enable the driver on all ARM platforms
  net: sh_eth: Set receive alignment correctly on all ARM platforms
  irda: sh_irda: Enable the driver on all ARM platforms
  pinctrl: sh-pfc: Enable the driver on all ARM platforms
  pwm: pwm-renesas-tpu: Enable the driver on all ARM platforms
  sh: intc: Enable the driver on all ARM platforms
  spi: sh_msiof: Enable the driver on all ARM platforms
  spi: sh_hspi: Enable the driver on all ARM platforms
  thermal: rcar-thermal: Enable the driver on all ARM platforms
  fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms

 drivers/dma/sh/Kconfig                | 2 +-
 drivers/dma/sh/shdmac.c               | 6 +++---
 drivers/i2c/busses/Kconfig            | 4 ++--
 drivers/input/keyboard/Kconfig        | 2 +-
 drivers/iommu/Kconfig                 | 2 +-
 drivers/media/platform/Kconfig        | 2 +-
 drivers/mmc/host/Kconfig              | 4 ++--
 drivers/mmc/host/tmio_mmc_dma.c       | 2 +-
 drivers/mtd/nand/Kconfig              | 2 +-
 drivers/net/ethernet/renesas/sh_eth.c | 2 +-
 drivers/net/ethernet/renesas/sh_eth.h | 2 +-
 drivers/net/irda/Kconfig              | 2 +-
 drivers/pinctrl/Makefile              | 2 +-
 drivers/pinctrl/sh-pfc/Kconfig        | 2 +-
 drivers/pwm/Kconfig                   | 2 +-
 drivers/sh/intc/Kconfig               | 2 +-
 drivers/spi/Kconfig                   | 4 ++--
 drivers/thermal/Kconfig               | 2 +-
 drivers/tty/serial/Kconfig            | 2 +-
 drivers/video/Kconfig                 | 6 +++---
 20 files changed, 27 insertions(+), 27 deletions(-)

-- 
Regards,

Laurent Pinchart



From laurent.pinchart+renesas at ideasonboard.com  Mon Oct 28 19:46:58 2013
From: laurent.pinchart+renesas at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 00:46:58 +0100
Subject: [PATCH 10/19] mtd: sh_flctl: Enable the driver on all ARM platforms
In-Reply-To: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Message-ID: <1383004027-25036-11-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

Renesas ARM platforms are transitioning from single-platform to
multi-platform kernels using the new ARCH_SHMOBILE_MULTI. Make the
driver available on all ARM platforms to enable it on both ARCH_SHMOBILE
and ARCH_SHMOBILE_MULTI and increase build testing coverage.

Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
---
 drivers/mtd/nand/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..f491f5b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -486,7 +486,7 @@ config MTD_NAND_MXC
 
 config MTD_NAND_SH_FLCTL
 	tristate "Support for NAND on Renesas SuperH FLCTL"
-	depends on SUPERH || ARCH_SHMOBILE
+	depends on SUPERH || ARM
 	help
 	  Several Renesas SuperH CPU has FLCTL. This option enables support
 	  for NAND Flash using FLCTL.
-- 
1.8.1.5



From sourav.poddar at ti.com  Tue Oct 29 01:57:39 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 29 Oct 2013 11:27:39 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <201310271745.17152.marex@denx.de>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271745.17152.marex@denx.de>
Message-ID: <526F4E53.1050706@ti.com>

Hi,
On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> Dear Sourav Poddar,
>
> [...]
>
>> +static int macronix_quad_enable(struct m25p *flash)
>> +{
>> +	int ret, val;
>> +	u8 cmd[2];
>> +	cmd[0] = OPCODE_WRSR;
>> +
>> +	val = read_sr(flash);
>> +	cmd[1] = val | SR_QUAD_EN_MX;
>> +	write_enable(flash);
>> +
>> +	spi_write(flash->spi,&cmd, 2);
>> +
>> +	if (wait_till_ready(flash))
>> +		return 1;
>> +
>> +	ret = read_sr(flash);
> Maybe read_sr() and read_cr() shall be fixed to return retval only and the val
> shall be passed to them as an argument pointer? Aka. ret = read_sr(flash,&val);
>
> That way, this dangerous construct below could become:
>
> if (!(val&  SR_....)) {
> 	dev_err();
> 	ret = -EINVAL;
> }
>
> return ret;
I was trying to work on it and realise, we dont need to pass val directly.
We can continue returning the val and can still cleanup the below code as
u suggetsed above.
if (!(ret & SR_....)) {
     dev_err();
     ret = -EINVAL;
}


> It will also let us prevent mixing of error codes and register values, which is
> pretty ugly practice.
>
>> +	if (!(ret>  0&&  (ret&  SR_QUAD_EN_MX))) {
>> +		dev_err(&flash->spi->dev,
>> +			"Macronix Quad bit not set");
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
> [...]
>
>> +static inline int set_quad_mode(struct m25p *flash, u32 jedec_id)
>> +{
>> +	int status;
>> +
>> +	switch (JEDEC_MFR(jedec_id)) {
>> +	case CFI_MFR_MACRONIX:
>> +		status = macronix_quad_enable(flash);
>> +		if (status) {
>> +			dev_err(&flash->spi->dev,
>> +				"Macronix quad not enable");
> "Macronix quad-read not enabled" would be more sensible, DTTO below.
>
>> +			return -EINVAL;
>> +		}
>> +		return status;
>> +	default:
>> +		status = spansion_quad_enable(flash);
>> +		if (status) {
>> +			dev_err(&flash->spi->dev,
>> +				"Spansion quad not enable");
>> +			return -EINVAL;
>> +		}
>> +		return status;
>> +	}
>> +}
> [...]
>
>> @@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
>>   	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>>   	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>>   	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
>> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
>> +	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
> I'm not convinced enabling 4-bit mode should be hard-coded in the MTD driver.
> There might be a board which uses this chip in 1-bit mode.
>
> We have a setup with Spansion chip here which uses 1-bit addressing in U-Boot,
> but uses 4-bit addressing in Linux. We use a DT property to configure the SPI
> bus width for that and I think that's a way to go. Note that there also are
> chips which use 2-bit wide SPI communication.
>
> [...]
>



From horms at verge.net.au  Tue Oct 29 02:04:27 2013
From: horms at verge.net.au (Simon Horman)
Date: Tue, 29 Oct 2013 15:04:27 +0900
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Message-ID: <20131029060427.GF11580@verge.net.au>

On Tue, Oct 29, 2013 at 12:46:48AM +0100, Laurent Pinchart wrote:
> Hello,
> 
> This patch series, based on v3.12-rc7, prepares various Renesas drivers
> for migration to multiplatform kernels by enabling their compilation or
> otherwise fixing them on all ARM platforms. The patches are pretty
> straightforward and are described in their commit message.
> 
> I'd like to get all these patches merged in v3.14. As they will need to go
> through their respective subsystems' trees, I would appreciate if all
> maintainers involved could notify me when they merge patches from this series
> in their tree to help me tracking the merge status. I don't plan to send pull
> requests individually for these patches, and I will repost patches
> individually if changes are requested during review.
> 
> If you believe the issue should be solved in a different way (for instance by
> removing the architecture dependency completely) please reply to the cover
> letter to let other maintainers chime in.

I think this is a step in a good direction.
However, I think it would be even better if the architecture dependency was
removed completely.

> 
> Cc: Chris Ball <cjb at laptop.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: David Woodhouse <dwmw2 at infradead.org>
> Cc: dmaengine at vger.kernel.org
> Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> Cc: Eduardo Valentin <eduardo.valentin at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Guennadi Liakhovetski <g.liakhovetski+renesas at gmail.com>
> Cc: Ian Molton <ian at mnementh.co.uk>
> Cc: iommu at lists.linux-foundation.org
> Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> Cc: Joerg Roedel <joro at 8bytes.org>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: linux-fbdev at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-input at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: linux-mmc at vger.kernel.org
> Cc: linux-mtd at lists.infradead.org
> Cc: linux-pm at vger.kernel.org
> Cc: linux-pwm at vger.kernel.org
> Cc: linux-serial at vger.kernel.org
> Cc: linux-spi at vger.kernel.org
> Cc: Magnus Damm <magnus.damm at gmail.com>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Mauro Carvalho Chehab <m.chehab at samsung.com>
> Cc: netdev at vger.kernel.org
> Cc: Samuel Ortiz <samuel at sortiz.org>
> Cc: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> Cc: Vinod Koul <vinod.koul at intel.com>
> Cc: Wolfram Sang <wsa at the-dreams.de>
> Cc: Zhang Rui <rui.zhang at intel.com>
> 
> Laurent Pinchart (19):
>   serial: sh-sci: Enable the driver on all ARM platforms
>   DMA: shdma: Enable the driver on all ARM platforms
>   i2c: sh_mobile: Enable the driver on all ARM platforms
>   input: sh_keysc: Enable the driver on all ARM platforms
>   iommu: shmobile: Enable the driver on all ARM platforms
>   i2c: rcar: Enable the driver on all ARM platforms
>   v4l: sh_vou: Enable the driver on all ARM platforms
>   mmc: sdhi: Enable the driver on all ARM platforms
>   mmc: sh_mmcif: Enable the driver on all ARM platforms
>   mtd: sh_flctl: Enable the driver on all ARM platforms
>   net: sh_eth: Set receive alignment correctly on all ARM platforms
>   irda: sh_irda: Enable the driver on all ARM platforms
>   pinctrl: sh-pfc: Enable the driver on all ARM platforms
>   pwm: pwm-renesas-tpu: Enable the driver on all ARM platforms
>   sh: intc: Enable the driver on all ARM platforms
>   spi: sh_msiof: Enable the driver on all ARM platforms
>   spi: sh_hspi: Enable the driver on all ARM platforms
>   thermal: rcar-thermal: Enable the driver on all ARM platforms
>   fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms
> 
>  drivers/dma/sh/Kconfig                | 2 +-
>  drivers/dma/sh/shdmac.c               | 6 +++---
>  drivers/i2c/busses/Kconfig            | 4 ++--
>  drivers/input/keyboard/Kconfig        | 2 +-
>  drivers/iommu/Kconfig                 | 2 +-
>  drivers/media/platform/Kconfig        | 2 +-
>  drivers/mmc/host/Kconfig              | 4 ++--
>  drivers/mmc/host/tmio_mmc_dma.c       | 2 +-
>  drivers/mtd/nand/Kconfig              | 2 +-
>  drivers/net/ethernet/renesas/sh_eth.c | 2 +-
>  drivers/net/ethernet/renesas/sh_eth.h | 2 +-
>  drivers/net/irda/Kconfig              | 2 +-
>  drivers/pinctrl/Makefile              | 2 +-
>  drivers/pinctrl/sh-pfc/Kconfig        | 2 +-
>  drivers/pwm/Kconfig                   | 2 +-
>  drivers/sh/intc/Kconfig               | 2 +-
>  drivers/spi/Kconfig                   | 4 ++--
>  drivers/thermal/Kconfig               | 2 +-
>  drivers/tty/serial/Kconfig            | 2 +-
>  drivers/video/Kconfig                 | 6 +++---
>  20 files changed, 27 insertions(+), 27 deletions(-)
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From g.liakhovetski at gmx.de  Tue Oct 29 05:12:17 2013
From: g.liakhovetski at gmx.de (Guennadi Liakhovetski)
Date: Tue, 29 Oct 2013 10:12:17 +0100 (CET)
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Message-ID: <Pine.LNX.4.64.1310291009121.8404@axis700.grange>

Hi Laurent

On Tue, 29 Oct 2013, Laurent Pinchart wrote:

> Hello,
> 
> This patch series, based on v3.12-rc7, prepares various Renesas drivers
> for migration to multiplatform kernels by enabling their compilation or
> otherwise fixing them on all ARM platforms. The patches are pretty
> straightforward and are described in their commit message.
> 
> I'd like to get all these patches merged in v3.14. As they will need to go
> through their respective subsystems' trees, I would appreciate if all
> maintainers involved could notify me when they merge patches from this series
> in their tree to help me tracking the merge status. I don't plan to send pull
> requests individually for these patches, and I will repost patches
> individually if changes are requested during review.
> 
> If you believe the issue should be solved in a different way (for instance by
> removing the architecture dependency completely) please reply to the cover
> letter to let other maintainers chime in.

Exactly this was my doubt. If we let these drivers build on all ARM 
platforms... Maybe we should just let them build everywhere? Unless there 
are real ARM dependencies. Maybe you could try to remove the restriction 
and try to build them all on x86?

Thanks
Guennadi

> 
> Cc: Chris Ball <cjb at laptop.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: David Woodhouse <dwmw2 at infradead.org>
> Cc: dmaengine at vger.kernel.org
> Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> Cc: Eduardo Valentin <eduardo.valentin at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Guennadi Liakhovetski <g.liakhovetski+renesas at gmail.com>
> Cc: Ian Molton <ian at mnementh.co.uk>
> Cc: iommu at lists.linux-foundation.org
> Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> Cc: Joerg Roedel <joro at 8bytes.org>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: linux-fbdev at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-input at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: linux-mmc at vger.kernel.org
> Cc: linux-mtd at lists.infradead.org
> Cc: linux-pm at vger.kernel.org
> Cc: linux-pwm at vger.kernel.org
> Cc: linux-serial at vger.kernel.org
> Cc: linux-spi at vger.kernel.org
> Cc: Magnus Damm <magnus.damm at gmail.com>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Mauro Carvalho Chehab <m.chehab at samsung.com>
> Cc: netdev at vger.kernel.org
> Cc: Samuel Ortiz <samuel at sortiz.org>
> Cc: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> Cc: Vinod Koul <vinod.koul at intel.com>
> Cc: Wolfram Sang <wsa at the-dreams.de>
> Cc: Zhang Rui <rui.zhang at intel.com>
> 
> Laurent Pinchart (19):
>   serial: sh-sci: Enable the driver on all ARM platforms
>   DMA: shdma: Enable the driver on all ARM platforms
>   i2c: sh_mobile: Enable the driver on all ARM platforms
>   input: sh_keysc: Enable the driver on all ARM platforms
>   iommu: shmobile: Enable the driver on all ARM platforms
>   i2c: rcar: Enable the driver on all ARM platforms
>   v4l: sh_vou: Enable the driver on all ARM platforms
>   mmc: sdhi: Enable the driver on all ARM platforms
>   mmc: sh_mmcif: Enable the driver on all ARM platforms
>   mtd: sh_flctl: Enable the driver on all ARM platforms
>   net: sh_eth: Set receive alignment correctly on all ARM platforms
>   irda: sh_irda: Enable the driver on all ARM platforms
>   pinctrl: sh-pfc: Enable the driver on all ARM platforms
>   pwm: pwm-renesas-tpu: Enable the driver on all ARM platforms
>   sh: intc: Enable the driver on all ARM platforms
>   spi: sh_msiof: Enable the driver on all ARM platforms
>   spi: sh_hspi: Enable the driver on all ARM platforms
>   thermal: rcar-thermal: Enable the driver on all ARM platforms
>   fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms
> 
>  drivers/dma/sh/Kconfig                | 2 +-
>  drivers/dma/sh/shdmac.c               | 6 +++---
>  drivers/i2c/busses/Kconfig            | 4 ++--
>  drivers/input/keyboard/Kconfig        | 2 +-
>  drivers/iommu/Kconfig                 | 2 +-
>  drivers/media/platform/Kconfig        | 2 +-
>  drivers/mmc/host/Kconfig              | 4 ++--
>  drivers/mmc/host/tmio_mmc_dma.c       | 2 +-
>  drivers/mtd/nand/Kconfig              | 2 +-
>  drivers/net/ethernet/renesas/sh_eth.c | 2 +-
>  drivers/net/ethernet/renesas/sh_eth.h | 2 +-
>  drivers/net/irda/Kconfig              | 2 +-
>  drivers/pinctrl/Makefile              | 2 +-
>  drivers/pinctrl/sh-pfc/Kconfig        | 2 +-
>  drivers/pwm/Kconfig                   | 2 +-
>  drivers/sh/intc/Kconfig               | 2 +-
>  drivers/spi/Kconfig                   | 4 ++--
>  drivers/thermal/Kconfig               | 2 +-
>  drivers/tty/serial/Kconfig            | 2 +-
>  drivers/video/Kconfig                 | 6 +++---
>  20 files changed, 27 insertions(+), 27 deletions(-)
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 

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


From laurent.pinchart at ideasonboard.com  Tue Oct 29 05:46:18 2013
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 10:46:18 +0100
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <Pine.LNX.4.64.1310291009121.8404@axis700.grange>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <Pine.LNX.4.64.1310291009121.8404@axis700.grange>
Message-ID: <4271216.r5b5qx4BLA@avalon>

Hi Simon and Guennadi,

On Tuesday 29 October 2013 10:12:17 Guennadi Liakhovetski wrote:
> On Tue, 29 Oct 2013, Laurent Pinchart wrote:
> > Hello,
> > 
> > This patch series, based on v3.12-rc7, prepares various Renesas drivers
> > for migration to multiplatform kernels by enabling their compilation or
> > otherwise fixing them on all ARM platforms. The patches are pretty
> > straightforward and are described in their commit message.
> > 
> > I'd like to get all these patches merged in v3.14. As they will need to go
> > through their respective subsystems' trees, I would appreciate if all
> > maintainers involved could notify me when they merge patches from this
> > series in their tree to help me tracking the merge status. I don't plan
> > to send pull requests individually for these patches, and I will repost
> > patches individually if changes are requested during review.
> > 
> > If you believe the issue should be solved in a different way (for instance
> > by removing the architecture dependency completely) please reply to the
> > cover letter to let other maintainers chime in.
> 
> Exactly this was my doubt. If we let these drivers build on all ARM
> platforms... Maybe we should just let them build everywhere? Unless there
> are real ARM dependencies. Maybe you could try to remove the restriction
> and try to build them all on x86?

My concern is that they might not build on some architectures for which I 
don't have a cross-compiler. For instance not all architecture define ioread32 
and iowrite32, which some drivers might rely on. What about depending on 
SUPERH || ARM || COMPILE_TEST to start with, in order not to push compilation 
breakages to mainline ?

> > Cc: Chris Ball <cjb at laptop.org>
> > Cc: "David S. Miller" <davem at davemloft.net>
> > Cc: David Woodhouse <dwmw2 at infradead.org>
> > Cc: dmaengine at vger.kernel.org
> > Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> > Cc: Eduardo Valentin <eduardo.valentin at ti.com>
> > Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Cc: Guennadi Liakhovetski <g.liakhovetski+renesas at gmail.com>
> > Cc: Ian Molton <ian at mnementh.co.uk>
> > Cc: iommu at lists.linux-foundation.org
> > Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> > Cc: Joerg Roedel <joro at 8bytes.org>
> > Cc: Linus Walleij <linus.walleij at linaro.org>
> > Cc: linux-fbdev at vger.kernel.org
> > Cc: linux-i2c at vger.kernel.org
> > Cc: linux-input at vger.kernel.org
> > Cc: linux-kernel at vger.kernel.org
> > Cc: linux-media at vger.kernel.org
> > Cc: linux-mmc at vger.kernel.org
> > Cc: linux-mtd at lists.infradead.org
> > Cc: linux-pm at vger.kernel.org
> > Cc: linux-pwm at vger.kernel.org
> > Cc: linux-serial at vger.kernel.org
> > Cc: linux-spi at vger.kernel.org
> > Cc: Magnus Damm <magnus.damm at gmail.com>
> > Cc: Mark Brown <broonie at kernel.org>
> > Cc: Mauro Carvalho Chehab <m.chehab at samsung.com>
> > Cc: netdev at vger.kernel.org
> > Cc: Samuel Ortiz <samuel at sortiz.org>
> > Cc: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> > Cc: Thierry Reding <thierry.reding at gmail.com>
> > Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> > Cc: Vinod Koul <vinod.koul at intel.com>
> > Cc: Wolfram Sang <wsa at the-dreams.de>
> > Cc: Zhang Rui <rui.zhang at intel.com>
> > 
> > Laurent Pinchart (19):
> >   serial: sh-sci: Enable the driver on all ARM platforms
> >   DMA: shdma: Enable the driver on all ARM platforms
> >   i2c: sh_mobile: Enable the driver on all ARM platforms
> >   input: sh_keysc: Enable the driver on all ARM platforms
> >   iommu: shmobile: Enable the driver on all ARM platforms
> >   i2c: rcar: Enable the driver on all ARM platforms
> >   v4l: sh_vou: Enable the driver on all ARM platforms
> >   mmc: sdhi: Enable the driver on all ARM platforms
> >   mmc: sh_mmcif: Enable the driver on all ARM platforms
> >   mtd: sh_flctl: Enable the driver on all ARM platforms
> >   net: sh_eth: Set receive alignment correctly on all ARM platforms
> >   irda: sh_irda: Enable the driver on all ARM platforms
> >   pinctrl: sh-pfc: Enable the driver on all ARM platforms
> >   pwm: pwm-renesas-tpu: Enable the driver on all ARM platforms
> >   sh: intc: Enable the driver on all ARM platforms
> >   spi: sh_msiof: Enable the driver on all ARM platforms
> >   spi: sh_hspi: Enable the driver on all ARM platforms
> >   thermal: rcar-thermal: Enable the driver on all ARM platforms
> >   fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms
> >  
> >  drivers/dma/sh/Kconfig                | 2 +-
> >  drivers/dma/sh/shdmac.c               | 6 +++---
> >  drivers/i2c/busses/Kconfig            | 4 ++--
> >  drivers/input/keyboard/Kconfig        | 2 +-
> >  drivers/iommu/Kconfig                 | 2 +-
> >  drivers/media/platform/Kconfig        | 2 +-
> >  drivers/mmc/host/Kconfig              | 4 ++--
> >  drivers/mmc/host/tmio_mmc_dma.c       | 2 +-
> >  drivers/mtd/nand/Kconfig              | 2 +-
> >  drivers/net/ethernet/renesas/sh_eth.c | 2 +-
> >  drivers/net/ethernet/renesas/sh_eth.h | 2 +-
> >  drivers/net/irda/Kconfig              | 2 +-
> >  drivers/pinctrl/Makefile              | 2 +-
> >  drivers/pinctrl/sh-pfc/Kconfig        | 2 +-
> >  drivers/pwm/Kconfig                   | 2 +-
> >  drivers/sh/intc/Kconfig               | 2 +-
> >  drivers/spi/Kconfig                   | 4 ++--
> >  drivers/thermal/Kconfig               | 2 +-
> >  drivers/tty/serial/Kconfig            | 2 +-
> >  drivers/video/Kconfig                 | 6 +++---
> >  20 files changed, 27 insertions(+), 27 deletions(-)

-- 
Regards,

Laurent Pinchart



From fabio.estevam at freescale.com  Tue Oct 29 06:54:44 2013
From: fabio.estevam at freescale.com (Fabio Estevam)
Date: Tue, 29 Oct 2013 08:54:44 -0200
Subject: [PATCH] mtd: gpmi: Remove unused set_geometry_by_ecc_info()
Message-ID: <1383044084-6532-1-git-send-email-fabio.estevam@freescale.com>

Commit 031e2777e0 (mtd: gpmi: fix ECC regression) removed the usage of 
set_geometry_by_ecc_info(), which causes the following build warning:

drivers/mtd/nand/gpmi-nand/gpmi-nand.c:123:13: warning: 'set_geometry_by_ecc_info' defined but not used [-Wunused-function]

Signed-off-by: Fabio Estevam <fabio.estevam at freescale.com>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 124 ---------------------------------
 1 file changed, 124 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 7ac2280..b13d41a 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -114,130 +114,6 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this)
 	return true;
 }
 
-/*
- * If we can get the ECC information from the nand chip, we do not
- * need to calculate them ourselves.
- *
- * We may have available oob space in this case.
- */
-static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this)
-{
-	struct bch_geometry *geo = &this->bch_geometry;
-	struct mtd_info *mtd = &this->mtd;
-	struct nand_chip *chip = mtd->priv;
-	struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree;
-	unsigned int block_mark_bit_offset;
-
-	if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
-		return false;
-
-	switch (chip->ecc_step_ds) {
-	case SZ_512:
-		geo->gf_len = 13;
-		break;
-	case SZ_1K:
-		geo->gf_len = 14;
-		break;
-	default:
-		dev_err(this->dev,
-			"unsupported nand chip. ecc bits : %d, ecc size : %d\n",
-			chip->ecc_strength_ds, chip->ecc_step_ds);
-		return false;
-	}
-	geo->ecc_chunk_size = chip->ecc_step_ds;
-	geo->ecc_strength = round_up(chip->ecc_strength_ds, 2);
-	if (!gpmi_check_ecc(this))
-		return false;
-
-	/* Keep the C >= O */
-	if (geo->ecc_chunk_size < mtd->oobsize) {
-		dev_err(this->dev,
-			"unsupported nand chip. ecc size: %d, oob size : %d\n",
-			chip->ecc_step_ds, mtd->oobsize);
-		return false;
-	}
-
-	/* The default value, see comment in the legacy_set_geometry(). */
-	geo->metadata_size = 10;
-
-	geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
-
-	/*
-	 * Now, the NAND chip with 2K page(data chunk is 512byte) shows below:
-	 *
-	 *    |                          P                            |
-	 *    |<----------------------------------------------------->|
-	 *    |                                                       |
-	 *    |                                        (Block Mark)   |
-	 *    |                      P'                      |      | |     |
-	 *    |<-------------------------------------------->|  D   | |  O' |
-	 *    |                                              |<---->| |<--->|
-	 *    V                                              V      V V     V
-	 *    +---+----------+-+----------+-+----------+-+----------+-+-----+
-	 *    | M |   data   |E|   data   |E|   data   |E|   data   |E|     |
-	 *    +---+----------+-+----------+-+----------+-+----------+-+-----+
-	 *                                                   ^              ^
-	 *                                                   |      O       |
-	 *                                                   |<------------>|
-	 *                                                   |              |
-	 *
-	 *	P : the page size for BCH module.
-	 *	E : The ECC strength.
-	 *	G : the length of Galois Field.
-	 *	N : The chunk count of per page.
-	 *	M : the metasize of per page.
-	 *	C : the ecc chunk size, aka the "data" above.
-	 *	P': the nand chip's page size.
-	 *	O : the nand chip's oob size.
-	 *	O': the free oob.
-	 *
-	 *	The formula for P is :
-	 *
-	 *	            E * G * N
-	 *	       P = ------------ + P' + M
-	 *                      8
-	 *
-	 * The position of block mark moves forward in the ECC-based view
-	 * of page, and the delta is:
-	 *
-	 *                   E * G * (N - 1)
-	 *             D = (---------------- + M)
-	 *                          8
-	 *
-	 * Please see the comment in legacy_set_geometry().
-	 * With the condition C >= O , we still can get same result.
-	 * So the bit position of the physical block mark within the ECC-based
-	 * view of the page is :
-	 *             (P' - D) * 8
-	 */
-	geo->page_size = mtd->writesize + geo->metadata_size +
-		(geo->gf_len * geo->ecc_strength * geo->ecc_chunk_count) / 8;
-
-	/* The available oob size we have. */
-	if (geo->page_size < mtd->writesize + mtd->oobsize) {
-		of->offset = geo->page_size - mtd->writesize;
-		of->length = mtd->oobsize - of->offset;
-	}
-
-	geo->payload_size = mtd->writesize;
-
-	geo->auxiliary_status_offset = ALIGN(geo->metadata_size, 4);
-	geo->auxiliary_size = ALIGN(geo->metadata_size, 4)
-				+ ALIGN(geo->ecc_chunk_count, 4);
-
-	if (!this->swap_block_mark)
-		return true;
-
-	/* For bit swap. */
-	block_mark_bit_offset = mtd->writesize * 8 -
-		(geo->ecc_strength * geo->gf_len * (geo->ecc_chunk_count - 1)
-				+ geo->metadata_size * 8);
-
-	geo->block_mark_byte_offset = block_mark_bit_offset / 8;
-	geo->block_mark_bit_offset  = block_mark_bit_offset % 8;
-	return true;
-}
-
 static int legacy_set_geometry(struct gpmi_nand_data *this)
 {
 	struct bch_geometry *geo = &this->bch_geometry;
-- 
1.8.1.2




From b32955 at freescale.com  Tue Oct 29 07:00:42 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Tue, 29 Oct 2013 19:00:42 +0800
Subject: [PATCH] mtd: gpmi: Remove unused set_geometry_by_ecc_info()
In-Reply-To: <1383044084-6532-1-git-send-email-fabio.estevam@freescale.com>
References: <1383044084-6532-1-git-send-email-fabio.estevam@freescale.com>
Message-ID: <526F955A.9000108@freescale.com>

? 2013?10?29? 18:54, Fabio Estevam ??:
> drivers/mtd/nand/gpmi-nand/gpmi-nand.c:123:13: warning: 'set_geometry_by_ecc_info' defined but not used [-Wunused-function]
thanks, but my another patch has fixed this issue, we should not remove
this functions:
http://lists.infradead.org/pipermail/linux-mtd/2013-October/049507.html

Huang Shijie



From dedekind1 at gmail.com  Tue Oct 29 09:06:20 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 29 Oct 2013 15:06:20 +0200
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <Pine.LNX.4.64.1310291009121.8404@axis700.grange>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <Pine.LNX.4.64.1310291009121.8404@axis700.grange>
Message-ID: <1383051980.29619.33.camel@sauron.fi.intel.com>

On Tue, 2013-10-29 at 10:12 +0100, Guennadi Liakhovetski wrote:
> Hi Laurent
> 
> On Tue, 29 Oct 2013, Laurent Pinchart wrote:
> 
> > Hello,
> > 
> > This patch series, based on v3.12-rc7, prepares various Renesas drivers
> > for migration to multiplatform kernels by enabling their compilation or
> > otherwise fixing them on all ARM platforms. The patches are pretty
> > straightforward and are described in their commit message.
> > 
> > I'd like to get all these patches merged in v3.14. As they will need to go
> > through their respective subsystems' trees, I would appreciate if all
> > maintainers involved could notify me when they merge patches from this series
> > in their tree to help me tracking the merge status. I don't plan to send pull
> > requests individually for these patches, and I will repost patches
> > individually if changes are requested during review.
> > 
> > If you believe the issue should be solved in a different way (for instance by
> > removing the architecture dependency completely) please reply to the cover
> > letter to let other maintainers chime in.
> 
> Exactly this was my doubt. If we let these drivers build on all ARM 
> platforms... Maybe we should just let them build everywhere? Unless there 
> are real ARM dependencies. Maybe you could try to remove the restriction 
> and try to build them all on x86?

If they have never been used on anything but ARM, why would you remove
ARM dependencies? Just for the sake of compile-checking?

Also, if ARM dependency is ever removed, all these should become 'n' by
default in the Kconfig, in order to make sure they do not slip into
defconfigs of different architectures.

-- 
Best Regards,
Artem Bityutskiy



From laurent.pinchart at ideasonboard.com  Tue Oct 29 09:22:28 2013
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 14:22:28 +0100
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1383051980.29619.33.camel@sauron.fi.intel.com>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <Pine.LNX.4.64.1310291009121.8404@axis700.grange>
 <1383051980.29619.33.camel@sauron.fi.intel.com>
Message-ID: <1844190.ApyucSZX8W@avalon>

Hi Artem,

On Tuesday 29 October 2013 15:06:20 Artem Bityutskiy wrote:
> On Tue, 2013-10-29 at 10:12 +0100, Guennadi Liakhovetski wrote:
> > On Tue, 29 Oct 2013, Laurent Pinchart wrote:
> > > Hello,
> > > 
> > > This patch series, based on v3.12-rc7, prepares various Renesas drivers
> > > for migration to multiplatform kernels by enabling their compilation or
> > > otherwise fixing them on all ARM platforms. The patches are pretty
> > > straightforward and are described in their commit message.
> > > 
> > > I'd like to get all these patches merged in v3.14. As they will need to
> > > go through their respective subsystems' trees, I would appreciate if all
> > > maintainers involved could notify me when they merge patches from this
> > > series in their tree to help me tracking the merge status. I don't plan
> > > to send pull requests individually for these patches, and I will repost
> > > patches individually if changes are requested during review.
> > > 
> > > If you believe the issue should be solved in a different way (for
> > > instance by removing the architecture dependency completely) please
> > > reply to the cover letter to let other maintainers chime in.
> > 
> > Exactly this was my doubt. If we let these drivers build on all ARM
> > platforms... Maybe we should just let them build everywhere? Unless there
> > are real ARM dependencies. Maybe you could try to remove the restriction
> > and try to build them all on x86?
> 
> If they have never been used on anything but ARM, why would you remove
> ARM dependencies? Just for the sake of compile-checking?
> 
> Also, if ARM dependency is ever removed, all these should become 'n' by
> default in the Kconfig, in order to make sure they do not slip into
> defconfigs of different architectures.

The idea is that, if ARM is neither a compile-time nor runtime dependency, it 
should not be specified in Kconfig. However, if the IP core has never been 
used on anything but SuperH and ARM, I don't think clobbering the config 
process with drivers that can't be used on the target architecture would be a 
really good idea, especially now that we have a COMPILE_TEST Kconfig option. 
My preference does goes to SUPERH || ARM || COMPILE_TEST over no dependency at 
all.

-- 
Regards,

Laurent Pinchart



From marex at denx.de  Tue Oct 29 10:01:05 2013
From: marex at denx.de (Marek Vasut)
Date: Tue, 29 Oct 2013 15:01:05 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526F4E53.1050706@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271745.17152.marex@denx.de> <526F4E53.1050706@ti.com>
Message-ID: <201310291501.06051.marex@denx.de>

Dear Sourav Poddar,

> Hi,
> 
> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> > Dear Sourav Poddar,
> > 
> > [...]
> > 
> >> +static int macronix_quad_enable(struct m25p *flash)
> >> +{
> >> +	int ret, val;
> >> +	u8 cmd[2];
> >> +	cmd[0] = OPCODE_WRSR;
> >> +
> >> +	val = read_sr(flash);
> >> +	cmd[1] = val | SR_QUAD_EN_MX;
> >> +	write_enable(flash);
> >> +
> >> +	spi_write(flash->spi,&cmd, 2);
> >> +
> >> +	if (wait_till_ready(flash))
> >> +		return 1;
> >> +
> >> +	ret = read_sr(flash);
> > 
> > Maybe read_sr() and read_cr() shall be fixed to return retval only and
> > the val shall be passed to them as an argument pointer? Aka. ret =
> > read_sr(flash,&val);
> > 
> > That way, this dangerous construct below could become:
> > 
> > if (!(val&  SR_....)) {
> > 
> > 	dev_err();
> > 	ret = -EINVAL;
> > 
> > }
> > 
> > return ret;
> 
> I was trying to work on it and realise, we dont need to pass val directly.
> We can continue returning the val and can still cleanup the below code as
> u suggetsed above.
> if (!(ret & SR_....)) {
>      dev_err();
>      ret = -EINVAL;
> }

Uh oh, no. This doesn't seem right. I'd like to be able to clearly check if the 
function failed to read the register altogether OR if not, check the returned 
value of the register. Mixing these two together won't do us good. But maybe I 
just fail to understand your proposal, if so, then I appologize.

[...]

Best regards,
Marek Vasut


From dedekind1 at gmail.com  Tue Oct 29 09:54:27 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 29 Oct 2013 15:54:27 +0200
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1844190.ApyucSZX8W@avalon>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <Pine.LNX.4.64.1310291009121.8404@axis700.grange>
 <1383051980.29619.33.camel@sauron.fi.intel.com> <1844190.ApyucSZX8W@avalon>
Message-ID: <1383054867.29619.34.camel@sauron.fi.intel.com>

On Tue, 2013-10-29 at 14:22 +0100, Laurent Pinchart wrote:
> > Also, if ARM dependency is ever removed, all these should become 'n' by
> > default in the Kconfig, in order to make sure they do not slip into
> > defconfigs of different architectures.
> 
> The idea is that, if ARM is neither a compile-time nor runtime dependency, it 
> should not be specified in Kconfig. However, if the IP core has never been 
> used on anything but SuperH and ARM, I don't think clobbering the config 
> process with drivers that can't be used on the target architecture would be a 
> really good idea, especially now that we have a COMPILE_TEST Kconfig option. 
> My preference does goes to SUPERH || ARM || COMPILE_TEST over no dependency at 
> all.

Ah, OK, I missed the entire COMPILE_TEST story.

-- 
Best Regards,
Artem Bityutskiy



From sourav.poddar at ti.com  Tue Oct 29 10:08:19 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 29 Oct 2013 19:38:19 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <201310291501.06051.marex@denx.de>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310271745.17152.marex@denx.de> <526F4E53.1050706@ti.com>
 <201310291501.06051.marex@denx.de>
Message-ID: <526FC153.1020004@ti.com>

Dear Marek Vasut,
On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
> Dear Sourav Poddar,
>
>> Hi,
>>
>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
>>> Dear Sourav Poddar,
>>>
>>> [...]
>>>
>>>> +static int macronix_quad_enable(struct m25p *flash)
>>>> +{
>>>> +	int ret, val;
>>>> +	u8 cmd[2];
>>>> +	cmd[0] = OPCODE_WRSR;
>>>> +
>>>> +	val = read_sr(flash);
>>>> +	cmd[1] = val | SR_QUAD_EN_MX;
>>>> +	write_enable(flash);
>>>> +
>>>> +	spi_write(flash->spi,&cmd, 2);
>>>> +
>>>> +	if (wait_till_ready(flash))
>>>> +		return 1;
>>>> +
>>>> +	ret = read_sr(flash);
>>> Maybe read_sr() and read_cr() shall be fixed to return retval only and
>>> the val shall be passed to them as an argument pointer? Aka. ret =
>>> read_sr(flash,&val);
>>>
>>> That way, this dangerous construct below could become:
>>>
>>> if (!(val&   SR_....)) {
>>>
>>> 	dev_err();
>>> 	ret = -EINVAL;
>>>
>>> }
>>>
>>> return ret;
>> I was trying to work on it and realise, we dont need to pass val directly.
>> We can continue returning the val and can still cleanup the below code as
>> u suggetsed above.
>> if (!(ret&  SR_....)) {
>>       dev_err();
>>       ret = -EINVAL;
>> }
> Uh oh, no. This doesn't seem right. I'd like to be able to clearly check if the
> function failed to read the register altogether OR if not, check the returned
> value of the register. Mixing these two together won't do us good. But maybe I
> just fail to understand your proposal, if so, then I appologize.
>
Yes, what I am trying to propose is to eliminate the return error check.
The check whether register read has happened correctly is embedded in
read_sr/read_cr function itself.
         if (retval < 0) {
                 dev_err(&flash->spi->dev, "error %d reading SR\n",
                                 (int) retval);
                 return retval;
         }
Same goes for read_cr.
So, if the above condition is not hit, we simply return the read value and
check it with the respective bits.

> [...]
>
> Best regards,
> Marek Vasut



From dedekind1 at gmail.com  Tue Oct 29 11:18:21 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 29 Oct 2013 17:18:21 +0200
Subject: [PATCH 1/1]  MTD: UBI:  try to avoid program data to NOR flash
 after erasure interrupted
In-Reply-To: <71CF8D7F32C5C24C9CD1D0E02D52498A770B1B97@NTXXIAMBX02.xacn.micron.com>
References: <71CF8D7F32C5C24C9CD1D0E02D52498A77082AC5@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A77082DDB@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED11@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED44@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED67@NTXXIAMBX02.xacn.micron.com>
 <1382779164.5901.1.camel@karhu.quadriga.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770B1B97@NTXXIAMBX02.xacn.micron.com>
Message-ID: <1383059901.29619.52.camel@sauron.fi.intel.com>

On Mon, 2013-10-28 at 04:54 +0000, Qi Wang ?? (qiwang) wrote:
> On Sa, 2013-10-26 at 05:19 +0000, Artem Bityutskiy wrote:
> >On Thu, 2013-10-10 at 08:28 +0000, Qi Wang ?? (qiwang) wrote:
> >> But I want to say the potential risk is if low level driver program data to 
> >> this block, it will get ?timeout error?. And the timeout period could be very 
> >> long(almost several minutes), during this period, any operation on NOR flash 
> >> cannot be accept. so program data to a erasure interrupted block isn?t a 
> >> sensible action. in order to avoid program a erasure interrupted block, 
> >> I suggest UBIFS can read this block before program data. the code changing as below:
> >
> >Yes, reading first sounds like a good idea. Would you please send a
> >patch implementing it?
> 
> From: Qi Wang <qiwang at micron.com>
> 
> nor_erase_prepare() will be called before erase a NOR flash, it will program '0'
> into a block to mark this block. But program data into a erasure interrupted block
> can cause program timtout(several minutes at most) error, could impact other 
> operation on NOR flash. So UBIFS can read this block first to avoid unneeded 
> program operation. 
> 
> This patch try to put read operation at at head of write operation in 
> nor_erase_prepare(), read out the data. 
> If the data is already corrupt, then no need to program any data into this block, 
> just go to erase this block.
> 
> Signed-off-by: Qi Wang <qiwang at qiwang@micron.com>
> ---
> diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> index bf79def..be6ab56 100644
> --- a/drivers/mtd/ubi/io.c
> +++ b/drivers/mtd/ubi/io.c
> @@ -509,26 +509,10 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
>  	struct ubi_vid_hdr vid_hdr;
>  
>  	/*
> -	 * It is important to first invalidate the EC header, and then the VID
> -	 * header. Otherwise a power cut may lead to valid EC header and
> -	 * invalid VID header, in which case UBI will treat this PEB as
> -	 * corrupted and will try to preserve it, and print scary warnings.
> -	 */
> -	addr = (loff_t)pnum * ubi->peb_size;
> -	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
> -	if (!err) {
> -		addr += ubi->vid_hdr_aloffset;
> -		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
> -		if (!err)
> -			return 0;
> -	}

How about structuring the code this way:

if (EC header is good)
     invalidate EC header()
if (VID header is good)
     invalidate VID header()

Then you'll handle the case when only one of the headers is already
corrupted.

-- 
Best Regards,
Artem Bityutskiy



From dedekind1 at gmail.com  Tue Oct 29 11:20:43 2013
From: dedekind1 at gmail.com (Artem Bityutskiy)
Date: Tue, 29 Oct 2013 17:20:43 +0200
Subject: Patching mkfs.ubifs.c for running under Windows ?
In-Reply-To: <CAFLxGvyt2w31v7v1cmvKBE6=hLkY1G-v31srsoQz82ktxg7SAg@mail.gmail.com>
References: <mailman.6.1379692801.23497.linux-mtd@lists.infradead.org>
 <7c74c0d714e8e87daebbfd0163642d71@localhost>
 <1382782672.5901.25.camel@karhu.quadriga.com>
 <CAGVrzcY7RD0AFvkPLvoCSe5iFFtwXnLthVepJ=XrR4bhMPN6_A@mail.gmail.com>
 <CAFLxGvyt2w31v7v1cmvKBE6=hLkY1G-v31srsoQz82ktxg7SAg@mail.gmail.com>
Message-ID: <1383060043.29619.54.camel@sauron.fi.intel.com>

On Mon, 2013-10-28 at 11:47 +0100, Richard Weinberger wrote:
> > https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches
> >
> > in particular:
> > https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/110-portability.patch
> > https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/120-cygwin_fixes.patch
> > https://dev.openwrt.org/browser/trunk/tools/mtd-utils/patches/134-freebsd_loff_t.patch
> >
> > Not sure how acceptable they look like to you?
> 
> Looks not that bad. :-)
> But why do you need the file "include/cygwin/bits-byteswap.h"?
> 
> Artem, what do you think?
> IMHO adding cygwin support is less intrusive than adding native win32 support.

I would clean-up these patches even more, and split them further. But
yes, it looks like these could be turned into something not so intrusive
and maintainable and be merged if MTD users need them.

-- 
Best Regards,
Artem Bityutskiy



From marex at denx.de  Tue Oct 29 11:27:33 2013
From: marex at denx.de (Marek Vasut)
Date: Tue, 29 Oct 2013 16:27:33 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526FC153.1020004@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291501.06051.marex@denx.de> <526FC153.1020004@ti.com>
Message-ID: <201310291627.34003.marex@denx.de>

Dear Sourav Poddar,

> Dear Marek Vasut,
> 
> On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
> > Dear Sourav Poddar,
> > 
> >> Hi,
> >> 
> >> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> >>> Dear Sourav Poddar,
> >>> 
> >>> [...]
> >>> 
> >>>> +static int macronix_quad_enable(struct m25p *flash)
> >>>> +{
> >>>> +	int ret, val;
> >>>> +	u8 cmd[2];
> >>>> +	cmd[0] = OPCODE_WRSR;
> >>>> +
> >>>> +	val = read_sr(flash);
> >>>> +	cmd[1] = val | SR_QUAD_EN_MX;
> >>>> +	write_enable(flash);
> >>>> +
> >>>> +	spi_write(flash->spi,&cmd, 2);
> >>>> +
> >>>> +	if (wait_till_ready(flash))
> >>>> +		return 1;
> >>>> +
> >>>> +	ret = read_sr(flash);
> >>> 
> >>> Maybe read_sr() and read_cr() shall be fixed to return retval only and
> >>> the val shall be passed to them as an argument pointer? Aka. ret =
> >>> read_sr(flash,&val);
> >>> 
> >>> That way, this dangerous construct below could become:
> >>> 
> >>> if (!(val&   SR_....)) {
> >>> 
> >>> 	dev_err();
> >>> 	ret = -EINVAL;
> >>> 
> >>> }
> >>> 
> >>> return ret;
> >> 
> >> I was trying to work on it and realise, we dont need to pass val
> >> directly. We can continue returning the val and can still cleanup the
> >> below code as u suggetsed above.
> >> if (!(ret&  SR_....)) {
> >> 
> >>       dev_err();
> >>       ret = -EINVAL;
> >> 
> >> }
> > 
> > Uh oh, no. This doesn't seem right. I'd like to be able to clearly check
> > if the function failed to read the register altogether OR if not, check
> > the returned value of the register. Mixing these two together won't do
> > us good. But maybe I just fail to understand your proposal, if so, then
> > I appologize.
> 
> Yes, what I am trying to propose is to eliminate the return error check.

But we want to be able to check if there is a failure :)

> The check whether register read has happened correctly is embedded in
> read_sr/read_cr function itself.
>          if (retval < 0) {
>                  dev_err(&flash->spi->dev, "error %d reading SR\n",
>                                  (int) retval);
>                  return retval;
>          }
> Same goes for read_cr.
> So, if the above condition is not hit, we simply return the read value and
> check it with the respective bits.

Look here:

 107 static int read_sr(struct m25p *flash)
 108 {
 109         ssize_t retval;
 110         u8 code = OPCODE_RDSR;
 111         u8 val;
 112 
 113         retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
 114 
 115         if (retval < 0) {
 116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
 117                                 (int) retval);
 118                 return retval;

here you return error value IFF spi_write_then_read() fails for some reason.

 119         }
 120 
 121         return val;

here you return actual value of the register.

 122 }

This is how I'd change the function to make it less error-prone:

*107 static int read_sr(struct m25p *flash, u8 *rval)
 108 {
 109         ssize_t retval;
 110         u8 code = OPCODE_RDSR;
 111         u8 val;
 112 
 113         retval = spi_write_then_read(flash->spi, &code, 1, &val, 1);
 114 
 115         if (retval < 0) {
 116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
 117                                 (int) retval);
 118                 return retval;
 119         }
*120         *rval = val;
*121         return 0;
 122 }

This way, you can check if the SPI read failed and if so, handle it in some way. 
The return value would only be valid if this function returned 0.

Best regards,
Marek Vasut


From broonie at kernel.org  Tue Oct 29 12:04:49 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 29 Oct 2013 09:04:49 -0700
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <20131029060427.GF11580@verge.net.au>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <20131029060427.GF11580@verge.net.au>
Message-ID: <20131029160449.GD16686@sirena.org.uk>

On Tue, Oct 29, 2013 at 03:04:27PM +0900, Simon Horman wrote:

> I think this is a step in a good direction.
> However, I think it would be even better if the architecture dependency was
> removed completely.

Yes, please.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131029/7aa427b4/attachment.sig>

From linus.walleij at linaro.org  Tue Oct 29 12:28:48 2013
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 29 Oct 2013 09:28:48 -0700
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Message-ID: <CACRpkdbKk=n=6tU=9fD05Gu9utpQSZ1qrK7EqLf5qwaV7eHBWA@mail.gmail.com>

On Mon, Oct 28, 2013 at 4:46 PM, Laurent Pinchart
<laurent.pinchart+renesas at ideasonboard.com> wrote:

> If you believe the issue should be solved in a different way (for instance by
> removing the architecture dependency completely) please reply to the cover
> letter to let other maintainers chime in.

I have no real opinions on whether this is a good itermediate step towards
complete arch-independence or not, but I just noticed that you still
have the <mach/*> hierarchy in mach-shmobile/include/mach/*, and
grep:ing around this seems totally unnecessary, I think it would be
easy to produce a patch set eliminating <mach/*> from shmobile.

(Usually we will just move all the headers down into the
mach-shmobile folder.)

Yours,
Linus Walleij


From sourav.poddar at ti.com  Tue Oct 29 12:52:09 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 29 Oct 2013 22:22:09 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <201310291627.34003.marex@denx.de>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291501.06051.marex@denx.de> <526FC153.1020004@ti.com>
 <201310291627.34003.marex@denx.de>
Message-ID: <526FE7B9.3000602@ti.com>

On Tuesday 29 October 2013 08:57 PM, Marek Vasut wrote:
> Dear Sourav Poddar,
>
>> Dear Marek Vasut,
>>
>> On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
>>> Dear Sourav Poddar,
>>>
>>>> Hi,
>>>>
>>>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
>>>>> Dear Sourav Poddar,
>>>>>
>>>>> [...]
>>>>>
>>>>>> +static int macronix_quad_enable(struct m25p *flash)
>>>>>> +{
>>>>>> +	int ret, val;
>>>>>> +	u8 cmd[2];
>>>>>> +	cmd[0] = OPCODE_WRSR;
>>>>>> +
>>>>>> +	val = read_sr(flash);
>>>>>> +	cmd[1] = val | SR_QUAD_EN_MX;
>>>>>> +	write_enable(flash);
>>>>>> +
>>>>>> +	spi_write(flash->spi,&cmd, 2);
>>>>>> +
>>>>>> +	if (wait_till_ready(flash))
>>>>>> +		return 1;
>>>>>> +
>>>>>> +	ret = read_sr(flash);
>>>>> Maybe read_sr() and read_cr() shall be fixed to return retval only and
>>>>> the val shall be passed to them as an argument pointer? Aka. ret =
>>>>> read_sr(flash,&val);
>>>>>
>>>>> That way, this dangerous construct below could become:
>>>>>
>>>>> if (!(val&    SR_....)) {
>>>>>
>>>>> 	dev_err();
>>>>> 	ret = -EINVAL;
>>>>>
>>>>> }
>>>>>
>>>>> return ret;
>>>> I was trying to work on it and realise, we dont need to pass val
>>>> directly. We can continue returning the val and can still cleanup the
>>>> below code as u suggetsed above.
>>>> if (!(ret&   SR_....)) {
>>>>
>>>>        dev_err();
>>>>        ret = -EINVAL;
>>>>
>>>> }
>>> Uh oh, no. This doesn't seem right. I'd like to be able to clearly check
>>> if the function failed to read the register altogether OR if not, check
>>> the returned value of the register. Mixing these two together won't do
>>> us good. But maybe I just fail to understand your proposal, if so, then
>>> I appologize.
>> Yes, what I am trying to propose is to eliminate the return error check.
> But we want to be able to check if there is a failure :)
>
>> The check whether register read has happened correctly is embedded in
>> read_sr/read_cr function itself.
>>           if (retval<  0) {
>>                   dev_err(&flash->spi->dev, "error %d reading SR\n",
>>                                   (int) retval);
>>                   return retval;
>>           }
>> Same goes for read_cr.
>> So, if the above condition is not hit, we simply return the read value and
>> check it with the respective bits.
> Look here:
>
>   107 static int read_sr(struct m25p *flash)
>   108 {
>   109         ssize_t retval;
>   110         u8 code = OPCODE_RDSR;
>   111         u8 val;
>   112
>   113         retval = spi_write_then_read(flash->spi,&code, 1,&val, 1);
>   114
>   115         if (retval<  0) {
>   116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
>   117                                 (int) retval);
>   118                 return retval;
>
> here you return error value IFF spi_write_then_read() fails for some reason.
>
>   119         }
>   120
>   121         return val;
>
> here you return actual value of the register.
>
>   122 }
>
> This is how I'd change the function to make it less error-prone:
>
> *107 static int read_sr(struct m25p *flash, u8 *rval)
>   108 {
>   109         ssize_t retval;
>   110         u8 code = OPCODE_RDSR;
>   111         u8 val;
>   112
>   113         retval = spi_write_then_read(flash->spi,&code, 1,&val, 1);
>   114
>   115         if (retval<  0) {
>   116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
>   117                                 (int) retval);
>   118                 return retval;
>   119         }
> *120         *rval = val;
> *121         return 0;
>   122 }
>
> This way, you can check if the SPI read failed and if so, handle it in some way.
> The return value would only be valid if this function returned 0.
>
I got this, but do you think its necessary to have two checks for verifying
whether read passed. ?
If I go by your code above, after returning from above,
check for return value for successful read
and then check the respective bit set(SR_*). ?

> Best regards,
> Marek Vasut



From laurent.pinchart at ideasonboard.com  Tue Oct 29 13:05:53 2013
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 18:05:53 +0100
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <20131029160449.GD16686@sirena.org.uk>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <20131029060427.GF11580@verge.net.au> <20131029160449.GD16686@sirena.org.uk>
Message-ID: <1577821.Q7gttkPE2J@avalon>

Hi Mark,

On Tuesday 29 October 2013 09:04:49 Mark Brown wrote:
> On Tue, Oct 29, 2013 at 03:04:27PM +0900, Simon Horman wrote:
> > I think this is a step in a good direction.
> > However, I think it would be even better if the architecture dependency
> > was removed completely.
> 
> Yes, please.

I've kept it for two reasons.

The first one is that I can't compile-test all those drivers on all 
architectures. The spi-sh-msiof driver, for instance, uses io(read|write)(16|
32) which are not available on all architectures. There might be other similar 
problems that I can't catch, and I don't want to introduce build breakages in 
the kernel.

The second reason is that, as the IP cores have never been used on anything 
but SuperH and ARM, I don't like the idea of clobbering the config process 
with drivers that are useless on the target architecture. Now that we have a 
COMPILE_TEST Kconfig option, my preference would thus go to SUPERH || ARM || 
COMPILE_TEST over no dependency at all.

-- 
Regards,

Laurent Pinchart
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131029/fb192e83/attachment.sig>

From marex at denx.de  Tue Oct 29 13:08:58 2013
From: marex at denx.de (Marek Vasut)
Date: Tue, 29 Oct 2013 18:08:58 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526FE7B9.3000602@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291627.34003.marex@denx.de> <526FE7B9.3000602@ti.com>
Message-ID: <201310291808.58939.marex@denx.de>

Dear Sourav Poddar,

> On Tuesday 29 October 2013 08:57 PM, Marek Vasut wrote:
> > Dear Sourav Poddar,
> > 
> >> Dear Marek Vasut,
> >> 
> >> On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
> >>> Dear Sourav Poddar,
> >>> 
> >>>> Hi,
> >>>> 
> >>>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> >>>>> Dear Sourav Poddar,
> >>>>> 
> >>>>> [...]
> >>>>> 
> >>>>>> +static int macronix_quad_enable(struct m25p *flash)
> >>>>>> +{
> >>>>>> +	int ret, val;
> >>>>>> +	u8 cmd[2];
> >>>>>> +	cmd[0] = OPCODE_WRSR;
> >>>>>> +
> >>>>>> +	val = read_sr(flash);
> >>>>>> +	cmd[1] = val | SR_QUAD_EN_MX;
> >>>>>> +	write_enable(flash);
> >>>>>> +
> >>>>>> +	spi_write(flash->spi,&cmd, 2);
> >>>>>> +
> >>>>>> +	if (wait_till_ready(flash))
> >>>>>> +		return 1;
> >>>>>> +
> >>>>>> +	ret = read_sr(flash);
> >>>>> 
> >>>>> Maybe read_sr() and read_cr() shall be fixed to return retval only
> >>>>> and the val shall be passed to them as an argument pointer? Aka. ret
> >>>>> = read_sr(flash,&val);
> >>>>> 
> >>>>> That way, this dangerous construct below could become:
> >>>>> 
> >>>>> if (!(val&    SR_....)) {
> >>>>> 
> >>>>> 	dev_err();
> >>>>> 	ret = -EINVAL;
> >>>>> 
> >>>>> }
> >>>>> 
> >>>>> return ret;
> >>>> 
> >>>> I was trying to work on it and realise, we dont need to pass val
> >>>> directly. We can continue returning the val and can still cleanup the
> >>>> below code as u suggetsed above.
> >>>> if (!(ret&   SR_....)) {
> >>>> 
> >>>>        dev_err();
> >>>>        ret = -EINVAL;
> >>>> 
> >>>> }
> >>> 
> >>> Uh oh, no. This doesn't seem right. I'd like to be able to clearly
> >>> check if the function failed to read the register altogether OR if
> >>> not, check the returned value of the register. Mixing these two
> >>> together won't do us good. But maybe I just fail to understand your
> >>> proposal, if so, then I appologize.
> >> 
> >> Yes, what I am trying to propose is to eliminate the return error check.
> > 
> > But we want to be able to check if there is a failure :)
> > 
> >> The check whether register read has happened correctly is embedded in
> >> read_sr/read_cr function itself.
> >> 
> >>           if (retval<  0) {
> >>           
> >>                   dev_err(&flash->spi->dev, "error %d reading SR\n",
> >>                   
> >>                                   (int) retval);
> >>                   
> >>                   return retval;
> >>           
> >>           }
> >> 
> >> Same goes for read_cr.
> >> So, if the above condition is not hit, we simply return the read value
> >> and check it with the respective bits.
> > 
> > Look here:
> >   107 static int read_sr(struct m25p *flash)
> >   108 {
> >   109         ssize_t retval;
> >   110         u8 code = OPCODE_RDSR;
> >   111         u8 val;
> >   112
> >   113         retval = spi_write_then_read(flash->spi,&code, 1,&val, 1);
> >   114
> >   115         if (retval<  0) {
> >   116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
> >   117                                 (int) retval);
> >   118                 return retval;
> > 
> > here you return error value IFF spi_write_then_read() fails for some
> > reason.
> > 
> >   119         }
> >   120
> >   121         return val;
> > 
> > here you return actual value of the register.
> > 
> >   122 }
> > 
> > This is how I'd change the function to make it less error-prone:
> > 
> > *107 static int read_sr(struct m25p *flash, u8 *rval)
> > 
> >   108 {
> >   109         ssize_t retval;
> >   110         u8 code = OPCODE_RDSR;
> >   111         u8 val;
> >   112
> >   113         retval = spi_write_then_read(flash->spi,&code, 1,&val, 1);
> >   114
> >   115         if (retval<  0) {
> >   116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
> >   117                                 (int) retval);
> >   118                 return retval;
> >   119         }
> > 
> > *120         *rval = val;
> > *121         return 0;
> > 
> >   122 }
> > 
> > This way, you can check if the SPI read failed and if so, handle it in
> > some way. The return value would only be valid if this function returned
> > 0.
> 
> I got this, but do you think its necessary to have two checks for verifying
> whether read passed. ?

Yes of course it is necessary, how else would you be able to tell if the value 
is valid ? Sure, you can depend on negative integer here and on the fact that 
the u8 will never be 32-bits wide (to produce a negative integer when the return 
value is valid), but personally I think this is error-prone as hell.

> If I go by your code above, after returning from above,
> check for return value for successful read
> and then check the respective bit set(SR_*). ?

Yes, you will be checking the bit in SR only if you are sure the value is valid.


From ezequiel.garcia at free-electrons.com  Tue Oct 29 13:12:10 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Tue, 29 Oct 2013 14:12:10 -0300
Subject: [PATCH v2 0/5] Assorted OMAP2 NAND clean-ups
In-Reply-To: <20131025114836.GD2489@localhost>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AE2A@DBDE04.ent.ti.com>
 <20131025114836.GD2489@localhost>
Message-ID: <20131029171209.GA20207@localhost>

Hey Pekon,

On Fri, Oct 25, 2013 at 08:48:36AM -0300, Ezequiel Garcia wrote:
> Pekon,
> 
> On Fri, Oct 25, 2013 at 11:15:57AM +0000, Gupta, Pekon wrote:
> > Hi,
> > 
> > > -----Original Message-----
> > > From: Ezequiel Garcia [mailto:ezequiel.garcia at free-electrons.com]
> > [...]
> > 
> > > Pekon, Brian: Do you think this solution might work for 8-bit and 16-bit
> > > devices?
> > > 
> > I think NAND_BUSWIDTH_AUTO (without GPMC changes) would fail in
> > following scenarios..
> > 
> > Case-1: configuring gpmc,device-width=1 from DT when using x16 device.
> 
> ... which is wrong. That's why we have a DT property to configure that.
> The GPMC *must* be properly configured.
> 
> > As your NAND driver is using NAND_BUSWIDTH_AUTO, it should
> > ignore this DT config, and based on ONFI params it should work as x16
> > 
> 
> Hm.. I don't think so. The auto-stuff is just for the NAND driver, not
> for the memory controller. I don't know much about hardware, but in my mind
> I imagine them as different controllers.
> 
> > Case-2: configuring gpmc,device-width=2 from DT when using x8 device.
> 
> ... which is also wrong.
> 
> Once again, you're mis-configuring the GPMC. We cannot expect the NAND
> driver to work properly if the GPMC is not properly initialized, don't
> you think?
> 
> > Actually having NAND_BUSWIDTH_AUTO would require change in GPMC
> > driver also.. please refer my comments in.. 
> > http://lists.infradead.org/pipermail/linux-mtd/2013-October/049284.html
> > 
> 
> Well, I think the approach should be different and much simpler: GPMC
> *must* be properly configured and then NAND can do ONFI detection
> starting in 8-bit and then switching to 16-bit if needed.
> 
> This is what this patch is doing: it _fixes_ the NAND driver ONFI detection,
> _provided_ the GPMC is well-prepared.
> 
> You seem to think that GPMC + NAND should be able to automagically detect
> the device and work, but I don't think that's even physically possible, for
> the reasons you have just exposed.
> 

Sorry to insist: any comments about this?

If you have access to the AM335xEVM (which has an 8-bit NAND, as far as I know)
and also to the Beaglebone 16-bit NAND cape, then you can test this patchset
with all the different combinations: 8-bit vs. 16-bit and array-based vs.
ONFI-based detection.

If it works, then problem solved. If it doesn't, I'm sure we can find a
solution. The driver is currently buggy, so we need to address this sooner
or later.

In addition, the outcome of our discussion will probably be helpful for other
drivers/controllers, since this ONFI issue is likely to be common.

If you can do the testing, that would be great: keep in mind that the
GPMC must be correctly configured at all times. You can use my recent
GPMC patchset for that (which also need some testing).

Thanks in advance,
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From sourav.poddar at ti.com  Tue Oct 29 13:12:29 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Tue, 29 Oct 2013 22:42:29 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <201310291808.58939.marex@denx.de>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291627.34003.marex@denx.de> <526FE7B9.3000602@ti.com>
 <201310291808.58939.marex@denx.de>
Message-ID: <526FEC7D.6060403@ti.com>

On Tuesday 29 October 2013 10:38 PM, Marek Vasut wrote:
> Dear Sourav Poddar,
>
>> On Tuesday 29 October 2013 08:57 PM, Marek Vasut wrote:
>>> Dear Sourav Poddar,
>>>
>>>> Dear Marek Vasut,
>>>>
>>>> On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
>>>>> Dear Sourav Poddar,
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
>>>>>>> Dear Sourav Poddar,
>>>>>>>
>>>>>>> [...]
>>>>>>>
>>>>>>>> +static int macronix_quad_enable(struct m25p *flash)
>>>>>>>> +{
>>>>>>>> +	int ret, val;
>>>>>>>> +	u8 cmd[2];
>>>>>>>> +	cmd[0] = OPCODE_WRSR;
>>>>>>>> +
>>>>>>>> +	val = read_sr(flash);
>>>>>>>> +	cmd[1] = val | SR_QUAD_EN_MX;
>>>>>>>> +	write_enable(flash);
>>>>>>>> +
>>>>>>>> +	spi_write(flash->spi,&cmd, 2);
>>>>>>>> +
>>>>>>>> +	if (wait_till_ready(flash))
>>>>>>>> +		return 1;
>>>>>>>> +
>>>>>>>> +	ret = read_sr(flash);
>>>>>>> Maybe read_sr() and read_cr() shall be fixed to return retval only
>>>>>>> and the val shall be passed to them as an argument pointer? Aka. ret
>>>>>>> = read_sr(flash,&val);
>>>>>>>
>>>>>>> That way, this dangerous construct below could become:
>>>>>>>
>>>>>>> if (!(val&     SR_....)) {
>>>>>>>
>>>>>>> 	dev_err();
>>>>>>> 	ret = -EINVAL;
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>> return ret;
>>>>>> I was trying to work on it and realise, we dont need to pass val
>>>>>> directly. We can continue returning the val and can still cleanup the
>>>>>> below code as u suggetsed above.
>>>>>> if (!(ret&    SR_....)) {
>>>>>>
>>>>>>         dev_err();
>>>>>>         ret = -EINVAL;
>>>>>>
>>>>>> }
>>>>> Uh oh, no. This doesn't seem right. I'd like to be able to clearly
>>>>> check if the function failed to read the register altogether OR if
>>>>> not, check the returned value of the register. Mixing these two
>>>>> together won't do us good. But maybe I just fail to understand your
>>>>> proposal, if so, then I appologize.
>>>> Yes, what I am trying to propose is to eliminate the return error check.
>>> But we want to be able to check if there is a failure :)
>>>
>>>> The check whether register read has happened correctly is embedded in
>>>> read_sr/read_cr function itself.
>>>>
>>>>            if (retval<   0) {
>>>>
>>>>                    dev_err(&flash->spi->dev, "error %d reading SR\n",
>>>>
>>>>                                    (int) retval);
>>>>
>>>>                    return retval;
>>>>
>>>>            }
>>>>
>>>> Same goes for read_cr.
>>>> So, if the above condition is not hit, we simply return the read value
>>>> and check it with the respective bits.
>>> Look here:
>>>    107 static int read_sr(struct m25p *flash)
>>>    108 {
>>>    109         ssize_t retval;
>>>    110         u8 code = OPCODE_RDSR;
>>>    111         u8 val;
>>>    112
>>>    113         retval = spi_write_then_read(flash->spi,&code, 1,&val, 1);
>>>    114
>>>    115         if (retval<   0) {
>>>    116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
>>>    117                                 (int) retval);
>>>    118                 return retval;
>>>
>>> here you return error value IFF spi_write_then_read() fails for some
>>> reason.
>>>
>>>    119         }
>>>    120
>>>    121         return val;
>>>
>>> here you return actual value of the register.
>>>
>>>    122 }
>>>
>>> This is how I'd change the function to make it less error-prone:
>>>
>>> *107 static int read_sr(struct m25p *flash, u8 *rval)
>>>
>>>    108 {
>>>    109         ssize_t retval;
>>>    110         u8 code = OPCODE_RDSR;
>>>    111         u8 val;
>>>    112
>>>    113         retval = spi_write_then_read(flash->spi,&code, 1,&val, 1);
>>>    114
>>>    115         if (retval<   0) {
>>>    116                 dev_err(&flash->spi->dev, "error %d reading SR\n",
>>>    117                                 (int) retval);
>>>    118                 return retval;
>>>    119         }
>>>
>>> *120         *rval = val;
>>> *121         return 0;
>>>
>>>    122 }
>>>
>>> This way, you can check if the SPI read failed and if so, handle it in
>>> some way. The return value would only be valid if this function returned
>>> 0.
>> I got this, but do you think its necessary to have two checks for verifying
>> whether read passed. ?
> Yes of course it is necessary, how else would you be able to tell if the value
> is valid ? Sure, you can depend on negative integer here and on the fact that
> the u8 will never be 32-bits wide (to produce a negative integer when the return
> value is valid), but personally I think this is error-prone as hell.
>
>> If I go by your code above, after returning from above,
>> check for return value for successful read
>> and then check the respective bit set(SR_*). ?
> Yes, you will be checking the bit in SR only if you are sure the value is valid.
hmm..alrite I will do the cleanup and send v2.


From broonie at kernel.org  Tue Oct 29 13:23:31 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 29 Oct 2013 10:23:31 -0700
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1577821.Q7gttkPE2J@avalon>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <20131029060427.GF11580@verge.net.au>
 <20131029160449.GD16686@sirena.org.uk> <1577821.Q7gttkPE2J@avalon>
Message-ID: <20131029172331.GA20251@sirena.org.uk>

On Tue, Oct 29, 2013 at 06:05:53PM +0100, Laurent Pinchart wrote:

> The first one is that I can't compile-test all those drivers on all 
> architectures. The spi-sh-msiof driver, for instance, uses io(read|write)(16|

Which architectures are these and is there not a symbol we can depend on
for them?

> 32) which are not available on all architectures. There might be other similar 
> problems that I can't catch, and I don't want to introduce build breakages in 
> the kernel.

This is easy enough to handle if we do run into issues, it seems better
to get things available than try to step through architecture by
architecture.

> The second reason is that, as the IP cores have never been used on anything 
> but SuperH and ARM, I don't like the idea of clobbering the config process 
> with drivers that are useless on the target architecture. Now that we have a 
> COMPILE_TEST Kconfig option, my preference would thus go to SUPERH || ARM || 
> COMPILE_TEST over no dependency at all.

That's not what you did, though - you're not adding COMPILE_TEST.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131029/c0101057/attachment.sig>

From laurent.pinchart at ideasonboard.com  Tue Oct 29 13:29:59 2013
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 18:29:59 +0100
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <20131029172331.GA20251@sirena.org.uk>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <1577821.Q7gttkPE2J@avalon> <20131029172331.GA20251@sirena.org.uk>
Message-ID: <1422562.0L87CDt5Gd@avalon>

Hi Mark,

On Tuesday 29 October 2013 10:23:31 Mark Brown wrote:
> On Tue, Oct 29, 2013 at 06:05:53PM +0100, Laurent Pinchart wrote:
> > The first one is that I can't compile-test all those drivers on all
> > architectures. The spi-sh-msiof driver, for instance, uses
> > io(read|write)(16|
>
> Which architectures are these and is there not a symbol we can depend on
> for them?

arch/cris for instance. We can use readl/writel instead (maybe it would be 
time to rationalize and document the I/O accessors across all architectures, 
but that's another topic).

My point is that there might be other issues that I won't be able to easily 
catch. This would break compilation for everybody for no reason, as the 
drivers are useless on non-SuperH, non-ARM platforms. That's why I believe 
COMPILE_TEST would be a better option as a first step.

> > 32) which are not available on all architectures. There might be other
> > similar problems that I can't catch, and I don't want to introduce build
> > breakages in the kernel.
> 
> This is easy enough to handle if we do run into issues, it seems better to
> get things available than try to step through architecture by architecture.
> 
> > The second reason is that, as the IP cores have never been used on
> > anything but SuperH and ARM, I don't like the idea of clobbering the
> > config process with drivers that are useless on the target architecture.
> > Now that we have a COMPILE_TEST Kconfig option, my preference would thus
> > go to SUPERH || ARM || COMPILE_TEST over no dependency at all.
> 
> That's not what you did, though - you're not adding COMPILE_TEST.

No, but I can add it :-) If this gets agreed upon, I'll respin the series with 
|| COMPILE_TEST.

-- 
Regards,

Laurent Pinchart
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131029/308736c6/attachment.sig>

From broonie at kernel.org  Tue Oct 29 13:58:34 2013
From: broonie at kernel.org (Mark Brown)
Date: Tue, 29 Oct 2013 10:58:34 -0700
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <1422562.0L87CDt5Gd@avalon>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <1577821.Q7gttkPE2J@avalon> <20131029172331.GA20251@sirena.org.uk>
 <1422562.0L87CDt5Gd@avalon>
Message-ID: <20131029175834.GD20251@sirena.org.uk>

On Tue, Oct 29, 2013 at 06:29:59PM +0100, Laurent Pinchart wrote:
> On Tuesday 29 October 2013 10:23:31 Mark Brown wrote:
> > On Tue, Oct 29, 2013 at 06:05:53PM +0100, Laurent Pinchart wrote:
> > > The first one is that I can't compile-test all those drivers on all
> > > architectures. The spi-sh-msiof driver, for instance, uses
> > > io(read|write)(16|

> > Which architectures are these and is there not a symbol we can depend on
> > for them?

> arch/cris for instance. We can use readl/writel instead (maybe it would be 
> time to rationalize and document the I/O accessors across all architectures, 
> but that's another topic).

It'd certainly be sensible, or adding a config option to depend on if
you rely on these functions.

> My point is that there might be other issues that I won't be able to easily 
> catch. This would break compilation for everybody for no reason, as the 
> drivers are useless on non-SuperH, non-ARM platforms. That's why I believe 
> COMPILE_TEST would be a better option as a first step.

Yes, it would - please do that.  Note that it won't stop anyone running
into build issues on other architectures though, it's just about
stopping Kconfig noise.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131029/f7cb98ae/attachment-0001.sig>

From sourav.poddar at ti.com  Tue Oct 29 14:34:08 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 00:04:08 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526FEC7D.6060403@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291627.34003.marex@denx.de> <526FE7B9.3000602@ti.com>
 <201310291808.58939.marex@denx.de> <526FEC7D.6060403@ti.com>
Message-ID: <526FFFA0.8040800@ti.com>

On Tuesday 29 October 2013 10:42 PM, Sourav Poddar wrote:
> On Tuesday 29 October 2013 10:38 PM, Marek Vasut wrote:
>> Dear Sourav Poddar,
>>
>>> On Tuesday 29 October 2013 08:57 PM, Marek Vasut wrote:
>>>> Dear Sourav Poddar,
>>>>
>>>>> Dear Marek Vasut,
>>>>>
>>>>> On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
>>>>>> Dear Sourav Poddar,
>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
>>>>>>>> Dear Sourav Poddar,
>>>>>>>>
>>>>>>>> [...]
>>>>>>>>
>>>>>>>>> +static int macronix_quad_enable(struct m25p *flash)
>>>>>>>>> +{
>>>>>>>>> +    int ret, val;
>>>>>>>>> +    u8 cmd[2];
>>>>>>>>> +    cmd[0] = OPCODE_WRSR;
>>>>>>>>> +
>>>>>>>>> +    val = read_sr(flash);
>>>>>>>>> +    cmd[1] = val | SR_QUAD_EN_MX;
>>>>>>>>> +    write_enable(flash);
>>>>>>>>> +
>>>>>>>>> +    spi_write(flash->spi,&cmd, 2);
>>>>>>>>> +
>>>>>>>>> +    if (wait_till_ready(flash))
>>>>>>>>> +        return 1;
>>>>>>>>> +
>>>>>>>>> +    ret = read_sr(flash);
>>>>>>>> Maybe read_sr() and read_cr() shall be fixed to return retval only
>>>>>>>> and the val shall be passed to them as an argument pointer? 
>>>>>>>> Aka. ret
>>>>>>>> = read_sr(flash,&val);
>>>>>>>>
>>>>>>>> That way, this dangerous construct below could become:
>>>>>>>>
>>>>>>>> if (!(val&     SR_....)) {
>>>>>>>>
>>>>>>>>     dev_err();
>>>>>>>>     ret = -EINVAL;
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> return ret;
>>>>>>> I was trying to work on it and realise, we dont need to pass val
>>>>>>> directly. We can continue returning the val and can still 
>>>>>>> cleanup the
>>>>>>> below code as u suggetsed above.
>>>>>>> if (!(ret&    SR_....)) {
>>>>>>>
>>>>>>>         dev_err();
>>>>>>>         ret = -EINVAL;
>>>>>>>
>>>>>>> }
>>>>>> Uh oh, no. This doesn't seem right. I'd like to be able to clearly
>>>>>> check if the function failed to read the register altogether OR if
>>>>>> not, check the returned value of the register. Mixing these two
>>>>>> together won't do us good. But maybe I just fail to understand your
>>>>>> proposal, if so, then I appologize.
>>>>> Yes, what I am trying to propose is to eliminate the return error 
>>>>> check.
>>>> But we want to be able to check if there is a failure :)
>>>>
>>>>> The check whether register read has happened correctly is embedded in
>>>>> read_sr/read_cr function itself.
>>>>>
>>>>>            if (retval<   0) {
>>>>>
>>>>>                    dev_err(&flash->spi->dev, "error %d reading SR\n",
>>>>>
>>>>>                                    (int) retval);
>>>>>
>>>>>                    return retval;
>>>>>
>>>>>            }
>>>>>
>>>>> Same goes for read_cr.
>>>>> So, if the above condition is not hit, we simply return the read 
>>>>> value
>>>>> and check it with the respective bits.
>>>> Look here:
>>>>    107 static int read_sr(struct m25p *flash)
>>>>    108 {
>>>>    109         ssize_t retval;
>>>>    110         u8 code = OPCODE_RDSR;
>>>>    111         u8 val;
>>>>    112
>>>>    113         retval = spi_write_then_read(flash->spi,&code, 
>>>> 1,&val, 1);
>>>>    114
>>>>    115         if (retval<   0) {
>>>>    116                 dev_err(&flash->spi->dev, "error %d reading 
>>>> SR\n",
>>>>    117                                 (int) retval);
>>>>    118                 return retval;
>>>>
>>>> here you return error value IFF spi_write_then_read() fails for some
>>>> reason.
>>>>
>>>>    119         }
>>>>    120
>>>>    121         return val;
>>>>
>>>> here you return actual value of the register.
>>>>
>>>>    122 }
>>>>
>>>> This is how I'd change the function to make it less error-prone:
>>>>
>>>> *107 static int read_sr(struct m25p *flash, u8 *rval)
>>>>
>>>>    108 {
>>>>    109         ssize_t retval;
>>>>    110         u8 code = OPCODE_RDSR;
>>>>    111         u8 val;
>>>>    112
>>>>    113         retval = spi_write_then_read(flash->spi,&code, 
>>>> 1,&val, 1);
>>>>    114
>>>>    115         if (retval<   0) {
>>>>    116                 dev_err(&flash->spi->dev, "error %d reading 
>>>> SR\n",
>>>>    117                                 (int) retval);
>>>>    118                 return retval;
>>>>    119         }
>>>>
>>>> *120         *rval = val;
>>>> *121         return 0;
>>>>
>>>>    122 }
>>>>
>>>> This way, you can check if the SPI read failed and if so, handle it in
>>>> some way. The return value would only be valid if this function 
>>>> returned
>>>> 0.
>>> I got this, but do you think its necessary to have two checks for 
>>> verifying
>>> whether read passed. ?
>> Yes of course it is necessary, how else would you be able to tell if 
>> the value
>> is valid ? Sure, you can depend on negative integer here and on the 
>> fact that
>> the u8 will never be 32-bits wide (to produce a negative integer when 
>> the return
>> value is valid), but personally I think this is error-prone as hell.
>>
>>> If I go by your code above, after returning from above,
>>> check for return value for successful read
>>> and then check the respective bit set(SR_*). ?
>> Yes, you will be checking the bit in SR only if you are sure the 
>> value is valid.
> hmm..alrite I will do the cleanup and send v2.
I think it will be better to take the above recommended cleanup as a 
seperate patch
on top of $subject patch? Since, read_sr is not only used by the pieces 
added in this patch.
There are other already available apis in the driver which make use of 
this function.
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From pekon at ti.com  Tue Oct 29 16:14:34 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Tue, 29 Oct 2013 20:14:34 +0000
Subject: [PATCH v2 0/5] Assorted OMAP2 NAND clean-ups
In-Reply-To: <20131025114836.GD2489@localhost>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AE2A@DBDE04.ent.ti.com>
 <20131025114836.GD2489@localhost>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2BADF@DBDE04.ent.ti.com>

Hi Ezequiel Garcia,

Sorry I'm bit out of my place.. so not able to sync often with mails..
However plz see my replies below..

[...]

> >
> > > Pekon, Brian: Do you think this solution might work for 8-bit and 16-bit
> > > devices?
> > >
> > I think NAND_BUSWIDTH_AUTO (without GPMC changes) would fail in
> > following scenarios..
> >
> > Case-1: configuring gpmc,device-width=1 from DT when using x16 device.
> 
> ... which is wrong. That's why we have a DT property to configure that.
> The GPMC *must* be properly configured.
> 
No, I think the main intention of using NAND_BUSWIDTH_AUTO is that
your controller should not depend on DT or any other user-input to detect
NAND bus-width, (whether its gpmc,device-width or anything else).


> > As your NAND driver is using NAND_BUSWIDTH_AUTO, it should
> > ignore this DT config, and based on ONFI params it should work as x16
> >
> 
> Hm.. I don't think so. The auto-stuff is just for the NAND driver, not
> for the memory controller. I don't know much about hardware, but in my
> mind
> I imagine them as different controllers.
> 
TI's GPMC hardware engine can do much more than supporting only
NAND devices, therefore there is an independent GPMC driver, and
dependent NAND driver. 
So when a NAND device is connected all GPMC driver does is initializes
GPMC hardware based on static DT bindings, and pass the control to
NAND driver. But there should be a mechanism to override these
static DT configurations done in GPMC driver by NAND driver.
(it is this piece which is missing today).


> > Case-2: configuring gpmc,device-width=2 from DT when using x8 device.
> 
> ... which is also wrong.
> 
> Once again, you're mis-configuring the GPMC. We cannot expect the NAND
> driver to work properly if the GPMC is not properly initialized, don't
> you think?
> 
> > Actually having NAND_BUSWIDTH_AUTO would require change in GPMC
> > driver also.. please refer my comments in..
> > http://lists.infradead.org/pipermail/linux-mtd/2013-October/049284.html
> >
> 
> Well, I think the approach should be different and much simpler: GPMC
> *must* be properly configured and then NAND can do ONFI detection
> starting in 8-bit and then switching to 16-bit if needed.
> 
> This is what this patch is doing: it _fixes_ the NAND driver ONFI detection,
> _provided_ the GPMC is well-prepared.
> 
> You seem to think that GPMC + NAND should be able to automagically detect
> the device and work, but I don't think that's even physically possible, for
> the reasons you have just exposed.
> 
> I think this fix is simple enough.
> 
No, I still think there should be a way to tell the user that there is a
mis-match between bus-width configured in DT, and that detected
by ONFI probe. If it was straight forward, this would have been already
accepted earlier :-)

http://lists.infradead.org/pipermail/linux-mtd/2013-October/049154.html

(read the comments from Brian by following above patch thread)

Problem is if there is a mis-match in your bus-width due to incorrect
GPMC DT binding configurations, still NAND probe and everything will
pass correctly, because nand_scan_ident() uses read_byte() which
returns same for both x8 and x16 devices.
You will find issues when you actually do page reads and writes. And
this is where you would see corrupted half-page data. And user
would be clueless on why he is seeing such erratic behavior.

This is why I added checks for mismatch of DT binding right during
nand probe(), in above mentioned patch. I could just remove calling
nand_scan_ident() second-time and it becomes your patch, but then
it would be just validating the DT setting, not pure auto-detection.


> 
> BTW: The GPMC code ignores the DT value in 'gpmc,device-width' and uses
> 'nand-bus-width' instead, but that's a different bug and a different fix :)
> 
I think you mean the opposie.. GPMC driver uses gpmc,device-width..
Refer: $KERNEL/arch/arm/mach-omap2/gpmc.c
@@gpmc_read_settings_dt(...)
	of_property_read_u32(np, "gpmc,device-width", &p->device_width);

'nand-bus-width' is not used anywhere instead..


with regards, pekon

From laurent.pinchart+renesas at ideasonboard.com  Tue Oct 29 18:37:35 2013
From: laurent.pinchart+renesas at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 23:37:35 +0100
Subject: [PATCH v2 00/19] Enable various Renesas drivers on all ARM platforms
Message-ID: <1383086274-11049-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

Hello,

This patch series, based on v3.12-rc7, prepares various Renesas drivers
for migration to multiplatform kernels by enabling their compilation or
otherwise fixing them on all ARM platforms. The patches are pretty
straightforward and are described in their commit message.

Changes since v1:

- The drivers can also be selected when COMPILE_TEST is enabled, regardless of
  the architecture. This should provide a good compromise between wide build
  test coverage and not clobbering configuration with drivers useless on
  non-SuperH, non-ARM platforms.

- DMA configuration is now unconditional in patch 08/19

I'd like to get all these patches merged in v3.14. As they will need to go
through their respective subsystems' trees, I would appreciate if all
maintainers involved could notify me when they merge patches from this series
in their tree to help me tracking the merge status. I don't plan to send pull
requests individually for these patches, and I will repost patches
individually if changes are requested during review.

If you believe the issue should be solved in a different way please reply to
the cover letter to let other maintainers chime in.

Cc: Chris Ball <cjb at laptop.org>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
Cc: Eduardo Valentin <eduardo.valentin at ti.com>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Guennadi Liakhovetski <g.liakhovetski+renesas at gmail.com>
Cc: Ian Molton <ian at mnementh.co.uk>
Cc: iommu at lists.linux-foundation.org
Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
Cc: Joerg Roedel <joro at 8bytes.org>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Magnus Damm <magnus.damm at gmail.com>
Cc: Mark Brown <broonie at kernel.org>
Cc: Mauro Carvalho Chehab <m.chehab at samsung.com>
Cc: Samuel Ortiz <samuel at sortiz.org>
Cc: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
Cc: Thierry Reding <thierry.reding at gmail.com>
Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
Cc: Vinod Koul <vinod.koul at intel.com>
Cc: Wolfram Sang <wsa at the-dreams.de>
Cc: Zhang Rui <rui.zhang at intel.com>
Cc: dmaengine at vger.kernel.org
Cc: linux-fbdev at vger.kernel.org
Cc: linux-i2c at vger.kernel.org
Cc: linux-input at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-media at vger.kernel.org
Cc: linux-mmc at vger.kernel.org
Cc: linux-mtd at lists.infradead.org
Cc: linux-pm at vger.kernel.org
Cc: linux-pwm at vger.kernel.org
Cc: linux-serial at vger.kernel.org
Cc: linux-spi at vger.kernel.org
Cc: netdev at vger.kernel.org

Laurent Pinchart (19):
  serial: sh-sci: Enable the driver on all ARM platforms
  DMA: shdma: Enable the driver on all ARM platforms
  i2c: sh_mobile: Enable the driver on all ARM platforms
  input: sh_keysc: Enable the driver on all ARM platforms
  iommu: shmobile: Enable the driver on all ARM platforms
  i2c: rcar: Enable the driver on all ARM platforms
  v4l: sh_vou: Enable the driver on all ARM platforms
  mmc: sdhi: Enable the driver on all ARM platforms
  mmc: sh_mmcif: Enable the driver on all ARM platforms
  mtd: sh_flctl: Enable the driver on all ARM platforms
  net: sh_eth: Set receive alignment correctly on all ARM platforms
  irda: sh_irda: Enable the driver on all ARM platforms
  pinctrl: sh-pfc: Enable the driver on all ARM platforms
  pwm: pwm-renesas-tpu: Enable the driver on all ARM platforms
  sh: intc: Enable the driver on all ARM platforms
  spi: sh_msiof: Enable the driver on all ARM platforms
  spi: sh_hspi: Enable the driver on all ARM platforms
  thermal: rcar-thermal: Enable the driver on all ARM platforms
  fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms

 drivers/dma/sh/Kconfig                | 2 +-
 drivers/dma/sh/shdmac.c               | 6 +++---
 drivers/i2c/busses/Kconfig            | 4 ++--
 drivers/input/keyboard/Kconfig        | 2 +-
 drivers/iommu/Kconfig                 | 2 +-
 drivers/media/platform/Kconfig        | 2 +-
 drivers/mmc/host/Kconfig              | 4 ++--
 drivers/mmc/host/tmio_mmc_dma.c       | 4 +---
 drivers/mtd/nand/Kconfig              | 2 +-
 drivers/net/ethernet/renesas/sh_eth.c | 2 +-
 drivers/net/ethernet/renesas/sh_eth.h | 2 +-
 drivers/net/irda/Kconfig              | 2 +-
 drivers/pinctrl/Makefile              | 2 +-
 drivers/pinctrl/sh-pfc/Kconfig        | 2 +-
 drivers/pwm/Kconfig                   | 2 +-
 drivers/sh/intc/Kconfig               | 2 +-
 drivers/spi/Kconfig                   | 4 ++--
 drivers/thermal/Kconfig               | 2 +-
 drivers/tty/serial/Kconfig            | 2 +-
 drivers/video/Kconfig                 | 6 +++---
 20 files changed, 27 insertions(+), 29 deletions(-)

-- 
Regards,

Laurent Pinchart



From laurent.pinchart+renesas at ideasonboard.com  Tue Oct 29 18:37:45 2013
From: laurent.pinchart+renesas at ideasonboard.com (Laurent Pinchart)
Date: Tue, 29 Oct 2013 23:37:45 +0100
Subject: [PATCH v2 10/19] mtd: sh_flctl: Enable the driver on all ARM platforms
In-Reply-To: <1383086274-11049-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
References: <1383086274-11049-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Message-ID: <1383086274-11049-11-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

Renesas ARM platforms are transitioning from single-platform to
multi-platform kernels using the new ARCH_SHMOBILE_MULTI. Make the
driver available on all ARM platforms to enable it on both ARCH_SHMOBILE
and ARCH_SHMOBILE_MULTI, and increase build testing coverage with
COMPILE_TEST.

Cc: David Woodhouse <dwmw2 at infradead.org>
Cc: linux-mtd at lists.infradead.org
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas at ideasonboard.com>
---
 drivers/mtd/nand/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index d885298..bc6bf36 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -486,7 +486,7 @@ config MTD_NAND_MXC
 
 config MTD_NAND_SH_FLCTL
 	tristate "Support for NAND on Renesas SuperH FLCTL"
-	depends on SUPERH || ARCH_SHMOBILE
+	depends on SUPERH || ARM || COMPILE_TEST
 	help
 	  Several Renesas SuperH CPU has FLCTL. This option enables support
 	  for NAND Flash using FLCTL.
-- 
1.8.1.5



From horms at verge.net.au  Tue Oct 29 20:05:03 2013
From: horms at verge.net.au (Simon Horman)
Date: Wed, 30 Oct 2013 09:05:03 +0900
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <20131029175834.GD20251@sirena.org.uk>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <1577821.Q7gttkPE2J@avalon> <20131029172331.GA20251@sirena.org.uk>
 <1422562.0L87CDt5Gd@avalon> <20131029175834.GD20251@sirena.org.uk>
Message-ID: <20131030000501.GE21262@verge.net.au>

On Tue, Oct 29, 2013 at 10:58:34AM -0700, Mark Brown wrote:
> On Tue, Oct 29, 2013 at 06:29:59PM +0100, Laurent Pinchart wrote:
> > On Tuesday 29 October 2013 10:23:31 Mark Brown wrote:
> > > On Tue, Oct 29, 2013 at 06:05:53PM +0100, Laurent Pinchart wrote:
> > > > The first one is that I can't compile-test all those drivers on all
> > > > architectures. The spi-sh-msiof driver, for instance, uses
> > > > io(read|write)(16|
> 
> > > Which architectures are these and is there not a symbol we can depend on
> > > for them?
> 
> > arch/cris for instance. We can use readl/writel instead (maybe it would be 
> > time to rationalize and document the I/O accessors across all architectures, 
> > but that's another topic).
> 
> It'd certainly be sensible, or adding a config option to depend on if
> you rely on these functions.
> 
> > My point is that there might be other issues that I won't be able to easily 
> > catch. This would break compilation for everybody for no reason, as the 
> > drivers are useless on non-SuperH, non-ARM platforms. That's why I believe 
> > COMPILE_TEST would be a better option as a first step.
> 
> Yes, it would - please do that.  Note that it won't stop anyone running
> into build issues on other architectures though, it's just about
> stopping Kconfig noise.

FWIW, I am happy with using COMPILE_TEST for this series.




From ezequiel.garcia at free-electrons.com  Tue Oct 29 20:16:14 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Tue, 29 Oct 2013 21:16:14 -0300
Subject: [PATCH v2 0/5] Assorted OMAP2 NAND clean-ups
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2BADF@DBDE04.ent.ti.com>
References: <1382696277-9063-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA2AE2A@DBDE04.ent.ti.com>
 <20131025114836.GD2489@localhost>
 <20980858CB6D3A4BAE95CA194937D5E73EA2BADF@DBDE04.ent.ti.com>
Message-ID: <20131030001613.GB2527@localhost>

Hey Pekon,

On Tue, Oct 29, 2013 at 08:14:34PM +0000, Gupta, Pekon wrote:
> 
> Sorry I'm bit out of my place.. so not able to sync often with mails..
> However plz see my replies below..
> 

Sure, no problem. Thanks for taking the time to discuss this!

[..]
> > 
> > You seem to think that GPMC + NAND should be able to automagically detect
> > the device and work, but I don't think that's even physically possible, for
> > the reasons you have just exposed.
> > 
> > I think this fix is simple enough.
> > 
> No, I still think there should be a way to tell the user that there is a
> mis-match between bus-width configured in DT, and that detected
> by ONFI probe. If it was straight forward, this would have been already
> accepted earlier :-)
> 
> http://lists.infradead.org/pipermail/linux-mtd/2013-October/049154.html
> 
> (read the comments from Brian by following above patch thread)
> 

Hmm... Well, I think your whole point of view is:

1. Mixing what's NAND controller and what's GPMC controller.
They are two different controllers, which means two different
drivers, and different parameters.

So from this perspective, trying to 'fix' GPMC configuration
from the NAND driver is a completely bad idea.

2. Trying to over-report the status to the user. The GPMC _must_
be properly configured before anything else. These NAND aren't plug
and play, so the 'user' knows the bus width anyway. If the user
has misconfigured the GPMC, then it's fine for things to not work.

Keep in mind the DT is not a configuration tool, but rather it's a
way to describe hardware. So, hardware parameters as bus width needs
to be properly described.

I've followed the above patch and, as far as I can read, Brian says: (quoting)

""
My opinion: the platform- and device-tree-provided buswidth is
unnecessary; it was previouisly only a suggestion which your driver
would readily discard, and it isn't really needed now. You can probably
get by with just NAND_BUSWIDTH_AUTO and (at most) a warning if the
auto-configured buswidth is different than the platform specified.

But the real point: you need to clearly communicate what you are
choosing in this patch. Either you want to

 (1) strictly follow the buswidth provided by the platform or

 (2) use the nand_base.c BUSWIDTH_AUTO automatic configuration.

Trying to mix both (as your patch currently does) just makes
everything worse.
""

Note that, in the above, Brian is talking about the NAND buswidth,
(not the GPMC). As he suggests, the proper thing to do is to simply
use BUSWIDTH_AUTO and discard any other parameter.

> > 
> > BTW: The GPMC code ignores the DT value in 'gpmc,device-width' and uses
> > 'nand-bus-width' instead, but that's a different bug and a different fix :)
> > 
> I think you mean the opposie.. GPMC driver uses gpmc,device-width..
> Refer: $KERNEL/arch/arm/mach-omap2/gpmc.c
> @@gpmc_read_settings_dt(...)
> 	of_property_read_u32(np, "gpmc,device-width", &p->device_width);
> 
> 'nand-bus-width' is not used anywhere instead..
> 

No, I meant just that: the current GPMC driver _ignores_ the DT value for
gpmc,device-width and overrides it with the 'nand-bus-width'.
See below for a stripped version of gpmc_nand_init():

int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
		   struct gpmc_timings *gpmc_t)
{
[...]
		if (gpmc_nand_data->of_node) {
			gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
		} else {
			/* .... */
		}

		s.device_nand = true;

		if (gpmc_nand_data->devsize == NAND_BUSWIDTH_16)
			s.device_width = GPMC_DEVWIDTH_16BIT;
		else
			s.device_width = GPMC_DEVWIDTH_8BIT;
}

The code first reads 'device_width' from gpmc_read_settings_dt(), and then
overrides it with the NAND buswidth value! Once again, the above repeats
the 'mixing parameter' scheme you are suggesting.

(I've already submitted a patchset fixing this. See here:
http://www.spinics.net/lists/arm-kernel/msg282594.html)

I think our current discussion can be summarized as this:

  * Should we fix the GPMC buswidth configuration, using the
    auto-detected NAND buswidth?

IMO, the answer is "NO!", as it results in fucked-up design.

But it's a _design_ choice, there's no technical reason why you can't
export some GPMC configuration function and call it from the driver.
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Tue Oct 29 23:59:57 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Tue, 29 Oct 2013 23:59:57 -0400
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up of
 supported ECC schemes
In-Reply-To: <20131024135258.GC9958@localhost>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <20131024135258.GC9958@localhost>
Message-ID: <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>

On Thu, Oct 24, 2013 at 9:52 AM, Ezequiel Garcia
<ezequiel.garcia at free-electrons.com> wrote:
> Just as suggestion, I think you should reconsider your 'upstream strategy'.
>
> On Thu, Oct 24, 2013 at 06:20:16PM +0530, Pekon Gupta wrote:
> [..]
>>
>> Pekon Gupta (10):
>>   ARM: OMAP2+: cleaned-up DT support of various ECC schemes
>>   mtd: nand: omap: combine different flavours of 1-bit hamming ecc schemes
>>   mtd: nand: omap: cleanup: replace local references with generic framework names
>
> IMHO, this patch about the dobule nand_scan_ident():
>>   mtd: nand: omap: use DT specified bus-width only for scanning NAND device
>
> is a fix unrelated to this series and can be pushed independently.
> Maybe you can try to send it as a one-patch fix?
>
>>   mtd:nand:omap2: clean-up BCHx_HW and BCHx_SW ECC configurations in device_probe
>>   mtd: nand: omap: clean-up ecc layout for BCH ecc schemes
>>   mtd: nand: omap: use drivers/mtd/nand/nand_bch.c wrapper for BCH ECC instead of lib/bch.c
>>   ARM: dts: AM33xx: updated default ECC scheme in nand-ecc-opt
>
> And also this patch:
>>   mtd: nand: omap: updated devm_xx for all resource allocation and free calls
>
> doesn't seem to belong to this series.
>
> I think tou could send those two independently and ask Brian to merge them earlier
> if appropriate.
>
> But again, this is just a suggestion.

I agree with Ezequiel's thoughts, since the excessive amount of noise
in this patch series has delayed it significantly. But at this point,
I think it has stabilized; we have reviews from the DT folks (thanks
guys; please comment if you have an official "ack" to give), and I
think we've retained backwards compatibility properly; I've combed
through it a few times over the months; we have a third-party tester;
and at this point, I'm sure we're all sick of this.

So, without further delay: pushed all patches except path 8 to l2-mtd.git.

Tony, you mentioned the DTS update in patch 8 going in via an ARM
tree? This patch is not urgent, and it should probably wait until we
know what release the rest of the series makes it into. This may
depend on David Woodhouse's recommendation, but I'm not sure this
series will have enough time baking in linux-next before entering
mainline in 3.13 (the merge window is approaching).

Pekon/Ezequiel/others: please feel free to send any follow up cleanups
for this driver. I'll take a look at what Ezequiel has already sent
out and see if it's still applicable on top.

Thanks,
Brian


From computersforpeace at gmail.com  Wed Oct 30 00:26:01 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 00:26:01 -0400
Subject: [PATCH v2] mtd: m25p80: add support for Macronix mx25l3255e
In-Reply-To: <201310271745.59262.marex@denx.de>
References: <1382568003-2356-1-git-send-email-computersforpeace@gmail.com>
 <201310271745.59262.marex@denx.de>
Message-ID: <20131030042601.GB7549@norris.computersforpeace.net>

On Sun, Oct 27, 2013 at 05:45:59PM +0100, Marek Vasut wrote:
> Dear Brian Norris,
> 
> > A new 32Mbit SPI NOR flash from Macronix. Nothing special.
> > 
> > Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> > Cc: Marek Vasut <marex at denx.de>
> 
> Nothing special :)
> 
> Reviewed-by: Marek Vasut <marex at denx.de>

Thanks :) Pushed to l2-mtd.git.

Brian


From weiyj.lk at gmail.com  Wed Oct 30 01:34:22 2013
From: weiyj.lk at gmail.com (Wei Yongjun)
Date: Wed, 30 Oct 2013 13:34:22 +0800
Subject: [PATCH -next] mtd: remove duplicated include from mtdcore.c
Message-ID: <CAPgLHd8=fLjqnKEoTB2C+7R=Nz7bdV0D5ttO29em=P8nX-Tvag@mail.gmail.com>

From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Remove duplicated include.

Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
---
 drivers/mtd/mtdcore.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 7189089..92311a5 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -37,7 +37,6 @@
 #include <linux/backing-dev.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
-#include <linux/major.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>



From b32955 at freescale.com  Wed Oct 30 02:27:59 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 30 Oct 2013 14:27:59 +0800
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526FFFA0.8040800@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291627.34003.marex@denx.de> <526FE7B9.3000602@ti.com>
 <201310291808.58939.marex@denx.de> <526FEC7D.6060403@ti.com>
 <526FFFA0.8040800@ti.com>
Message-ID: <5270A6EF.2020208@freescale.com>

? 2013?10?30? 02:34, Sourav Poddar ??:
> I think it will be better to take the above recommended cleanup as a 
> seperate patch
> on top of $subject patch? Since, read_sr is not only used by the 
> pieces added in this patch.
> There are other already available apis in the driver which make use of 
> this function. 
yes, I also think use a seperate patch to fix the read_sr() (If you want 
to change it.)

Btw, please add the version info, such "PATCH V3", in the title of your 
new patch.

thanks
Huang Shijie



From sourav.poddar at ti.com  Wed Oct 30 02:46:55 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 12:16:55 +0530
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270A6EF.2020208@freescale.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291627.34003.marex@denx.de> <526FE7B9.3000602@ti.com>
 <201310291808.58939.marex@denx.de> <526FEC7D.6060403@ti.com>
 <526FFFA0.8040800@ti.com> <5270A6EF.2020208@freescale.com>
Message-ID: <5270AB5F.8060800@ti.com>

Hi Huang,
On Wednesday 30 October 2013 11:57 AM, Huang Shijie wrote:
> ? 2013?10?30? 02:34, Sourav Poddar ??:
>> I think it will be better to take the above recommended cleanup as a 
>> seperate patch
>> on top of $subject patch? Since, read_sr is not only used by the 
>> pieces added in this patch.
>> There are other already available apis in the driver which make use 
>> of this function. 
> yes, I also think use a seperate patch to fix the read_sr() (If you 
> want to change it.)
>
> Btw, please add the version info, such "PATCH V3", in the title of 
> your new patch.
>
So done, I will try to clean up Marek's suggestion as a seperate patch 
once the $subject patch
is done and dusted.

There was a small comment by Marek on chaning the error print info, If 
there are no
further comments on $subject patch, I will go ahead and fix that small 
comments and resend
the series.
I did prefer to name it as V2 to have consistency with this thread. ?
> thanks
> Huang Shijie
>



From b32955 at freescale.com  Wed Oct 30 02:54:26 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 30 Oct 2013 14:54:26 +0800
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270AB5F.8060800@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291627.34003.marex@denx.de> <526FE7B9.3000602@ti.com>
 <201310291808.58939.marex@denx.de> <526FEC7D.6060403@ti.com>
 <526FFFA0.8040800@ti.com> <5270A6EF.2020208@freescale.com>
 <5270AB5F.8060800@ti.com>
Message-ID: <5270AD22.7070501@freescale.com>

? 2013?10?30? 14:46, Sourav Poddar ??:
> I did prefer to name it as V2 to have consistency with this thread. ? 
it's okay. :)

thanks
Huang Shijie



From sourav.poddar at ti.com  Wed Oct 30 03:22:45 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 12:52:45 +0530
Subject: [PATCHv2] drivers: mtd: m25p80: Add quad read support.
Message-ID: <1383117765-31732-1-git-send-email-sourav.poddar@ti.com>

Some flash also support quad read mode.
Adding support for adding quad mode in m25p80
for spansion and macronix flash.

Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
---
v1->v2:
Small dev_err message fix to make it
mode appropriate.
v1: http://patchwork.ozlabs.org/patch/286109/

There is one cleanup suggestion from Marek Vasut on read_sr
value. I will take that up as a seperate patch, once this 
patch gets done.
 drivers/mtd/devices/m25p80.c |  160 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 155 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index d6c5c57..921e30e 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -41,6 +41,7 @@
 #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
 #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ        0x6b    /* Read data bytes */
 #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
 #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
 #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
@@ -48,10 +49,12 @@
 #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
+#define	OPCODE_RDCR             0x35    /* Read configuration register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ_4B	0x6c    /* Read data bytes */
 #define	OPCODE_PP_4B		0x12	/* Page program (up to 256 bytes) */
 #define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
 
@@ -76,6 +79,10 @@
 #define	SR_BP2			0x10	/* Block protect 2 */
 #define	SR_SRWD			0x80	/* SR write protect */
 
+/* Configuration Register bits. */
+#define CR_QUAD_EN_SPAN		0x2     /* Spansion Quad I/O */
+#define SR_QUAD_EN_MX		0x40    /* Macronix Quad I/O */
+
 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
 #define	MAX_CMD_SIZE		6
@@ -95,6 +102,7 @@ struct m25p {
 	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
+	bool                    quad_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -131,6 +139,26 @@ static int read_sr(struct m25p *flash)
 }
 
 /*
+ * Read configuration register, returning its value in the
+ * location. Return the configuration register value.
+ * Returns negative if error occured.
+ */
+static int read_cr(struct m25p *flash)
+{
+	u8 code = OPCODE_RDCR;
+	int ret;
+	u8 val;
+
+	ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
@@ -220,6 +248,95 @@ static int wait_till_ready(struct m25p *flash)
 }
 
 /*
+ * Write status Register and configuration register with 2 bytes
+ * The first byte will be written to the status register, while the
+ * second byte will be written to the configuration register.
+ * Return negative if error occured.
+ */
+static int write_sr_cr(struct m25p *flash, u16 val)
+{
+	flash->command[0] = OPCODE_WRSR;
+	flash->command[1] = val & 0xff;
+	flash->command[2] = (val >> 8);
+
+	return spi_write(flash->spi, flash->command, 3);
+}
+
+static int macronix_quad_enable(struct m25p *flash)
+{
+	int ret, val;
+	u8 cmd[2];
+	cmd[0] = OPCODE_WRSR;
+
+	val = read_sr(flash);
+	cmd[1] = val | SR_QUAD_EN_MX;
+	write_enable(flash);
+
+	spi_write(flash->spi, &cmd, 2);
+
+	if (wait_till_ready(flash))
+		return 1;
+
+	ret = read_sr(flash);
+	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+		dev_err(&flash->spi->dev,
+			"Macronix Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int spansion_quad_enable(struct m25p *flash)
+{
+	int ret;
+	int quad_en = CR_QUAD_EN_SPAN << 8;
+
+	write_enable(flash);
+
+	ret = write_sr_cr(flash, quad_en);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev,
+			"error while writing configuration register");
+		return -EINVAL;
+	}
+
+	/* read back and check it */
+	ret = read_cr(flash);
+	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+		dev_err(&flash->spi->dev,
+			"Spansion Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline int set_quad_mode(struct m25p *flash, u32 jedec_id)
+{
+	int status;
+
+	switch (JEDEC_MFR(jedec_id)) {
+	case CFI_MFR_MACRONIX:
+		status = macronix_quad_enable(flash);
+		if (status) {
+			dev_err(&flash->spi->dev,
+				"Macronix quad-read not enabled");
+			return -EINVAL;
+		}
+		return status;
+	default:
+		status = spansion_quad_enable(flash);
+		if (status) {
+			dev_err(&flash->spi->dev,
+				"Spansion quad-read not enabled");
+			return -EINVAL;
+		}
+		return status;
+	}
+}
+
+/*
  * Erase the whole flash memory
  *
  * Returns 0 if successful, non-zero otherwise.
@@ -253,11 +370,24 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
 	cmd[4] = addr >> (flash->addr_width * 8 - 32);
 }
 
+/*
+ * Dummy Cycle calculation for fast and quad read.
+ * It can be used to support more commands with
+ * different dummy cycle requirement.
+ */
 static int m25p_cmdsz(struct m25p *flash)
 {
 	return 1 + flash->addr_width;
 }
 
+static inline int m25p80_dummy_cycles_read(struct m25p *flash)
+{
+	if (flash->quad_read || flash->fast_read)
+		return 1;
+
+	return 0;
+}
+
 /*
  * Erase one sector of flash memory at offset ``offset'' which is any
  * address within the sector which should be erased.
@@ -368,9 +498,10 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	memset(t, 0, (sizeof t));
 
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
+	t[0].len = m25p_cmdsz(flash) + m25p80_dummy_cycles_read(flash);
 	spi_message_add_tail(&t[0], &m);
 
+	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;
 	t[1].rx_buf = buf;
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
@@ -392,7 +523,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	spi_sync(flash->spi, &m);
 
 	*retlen = m.actual_length - m25p_cmdsz(flash) -
-			(flash->fast_read ? 1 : 0);
+			m25p80_dummy_cycles_read(flash);
 
 	mutex_unlock(&flash->lock);
 
@@ -698,6 +829,7 @@ struct flash_info {
 #define	SST_WRITE	0x04		/* use SST byte programming */
 #define	M25P_NO_FR	0x08		/* Can't do fastread */
 #define	SECT_4K_PMC	0x10		/* OPCODE_BE_4K_PMC works uniformly */
+#define	M25P80_QUAD_READ	0x20    /* Flash supports Quad Read */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@@ -774,7 +906,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
 
 	/* Micron */
 	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
@@ -794,7 +926,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
 	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, M25P80_QUAD_READ) },
 	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -936,6 +1068,7 @@ static int m25p_probe(struct spi_device *spi)
 	unsigned			i;
 	struct mtd_part_parser_data	ppdata;
 	struct device_node __maybe_unused *np = spi->dev.of_node;
+	int ret;
 
 #ifdef CONFIG_MTD_OF_PARTS
 	if (!of_device_is_available(np))
@@ -1055,6 +1188,15 @@ static int m25p_probe(struct spi_device *spi)
 	flash->page_size = info->page_size;
 	flash->mtd.writebufsize = flash->page_size;
 
+	if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
+		ret = set_quad_mode(flash, info->jedec_id);
+		if (ret) {
+			dev_err(&flash->spi->dev, "quad mode not supported\n");
+			return ret;
+		}
+		flash->quad_read = true;
+	}
+
 	if (np)
 		/* If we were instantiated by DT, use it */
 		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
@@ -1067,7 +1209,9 @@ static int m25p_probe(struct spi_device *spi)
 		flash->fast_read = false;
 
 	/* Default commands */
-	if (flash->fast_read)
+	if (flash->quad_read)
+		flash->read_opcode = OPCODE_QUAD_READ;
+	else if (flash->fast_read)
 		flash->read_opcode = OPCODE_FAST_READ;
 	else
 		flash->read_opcode = OPCODE_NORM_READ;
@@ -1081,6 +1225,12 @@ static int m25p_probe(struct spi_device *spi)
 		flash->addr_width = 4;
 		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
 			/* Dedicated 4-byte command set */
+			if (flash->quad_read)
+				flash->read_opcode = OPCODE_QUAD_READ_4B;
+			else
+				flash->read_opcode = flash->fast_read ?
+					OPCODE_FAST_READ_4B :
+					OPCODE_NORM_READ_4B;
 			flash->read_opcode = flash->fast_read ?
 				OPCODE_FAST_READ_4B :
 				OPCODE_NORM_READ_4B;
-- 
1.7.1



From b32955 at freescale.com  Wed Oct 30 03:58:31 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 30 Oct 2013 15:58:31 +0800
Subject: [PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <1383117765-31732-1-git-send-email-sourav.poddar@ti.com>
References: <1383117765-31732-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <5270BC27.40000@freescale.com>

? 2013?10?30? 15:22, Sourav Poddar ??:
> 	struct device_node __maybe_unused *np = spi->dev.of_node;
you'd better rebase this patch on the latest l2-mtd.

this line has been removed in the latest code.


thanks
Huang Shijie



From sourav.poddar at ti.com  Wed Oct 30 04:41:40 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 14:11:40 +0530
Subject: [PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270BC27.40000@freescale.com>
References: <1383117765-31732-1-git-send-email-sourav.poddar@ti.com>
 <5270BC27.40000@freescale.com>
Message-ID: <5270C644.1020405@ti.com>

On Wednesday 30 October 2013 01:28 PM, Huang Shijie wrote:
> ? 2013?10?30? 15:22, Sourav Poddar ??:
>>     struct device_node __maybe_unused *np = spi->dev.of_node;
> you'd better rebase this patch on the latest l2-mtd.
>
> this line has been removed in the latest code.
>
Ok.
>
> thanks
> Huang Shijie
>



From ezequiel.garcia at free-electrons.com  Wed Oct 30 05:16:16 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 30 Oct 2013 06:16:16 -0300
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up of
 supported ECC schemes
In-Reply-To: <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <20131024135258.GC9958@localhost>
 <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>
Message-ID: <20131030091615.GA2453@localhost>

On Tue, Oct 29, 2013 at 11:59:57PM -0400, Brian Norris wrote:
> 
> Pekon/Ezequiel/others: please feel free to send any follow up cleanups
> for this driver. I'll take a look at what Ezequiel has already sent
> out and see if it's still applicable on top.
> 

They won't. I'll prepare a new patch in top of latest l2-mtd.

It's good to see this DT discussion finally coming to an end! Good job!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From sourav.poddar at ti.com  Wed Oct 30 05:20:02 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 14:50:02 +0530
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
Message-ID: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>

Some flash also support quad read mode.
Adding support for adding quad mode in m25p80
for spansion and macronix flash.

Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
---
Rebase this on latest l2mtd.
v1->v2:
Small dev_err message fix to make it
mode appropriate.
v1: http://patchwork.ozlabs.org/patch/286109/

There is one cleanup suggestion from Marek Vasut on read_sr
value. I will take that up as a seperate patch, once this 
patch gets done.


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

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5897889..ba4dd8b 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -41,6 +41,7 @@
 #define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
 #define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ        0x6b    /* Read data bytes */
 #define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
 #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
 #define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
@@ -48,10 +49,12 @@
 #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
 #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
 #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
+#define	OPCODE_RDCR             0x35    /* Read configuration register */
 
 /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
 #define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
 #define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high frequency) */
+#define	OPCODE_QUAD_READ_4B	0x6c    /* Read data bytes */
 #define	OPCODE_PP_4B		0x12	/* Page program (up to 256 bytes) */
 #define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) */
 
@@ -76,6 +79,10 @@
 #define	SR_BP2			0x10	/* Block protect 2 */
 #define	SR_SRWD			0x80	/* SR write protect */
 
+/* Configuration Register bits. */
+#define CR_QUAD_EN_SPAN		0x2     /* Spansion Quad I/O */
+#define SR_QUAD_EN_MX		0x40    /* Macronix Quad I/O */
+
 /* Define max times to check status register before we give up. */
 #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
 #define	MAX_CMD_SIZE		6
@@ -95,6 +102,7 @@ struct m25p {
 	u8			program_opcode;
 	u8			*command;
 	bool			fast_read;
+	bool                    quad_read;
 };
 
 static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -131,6 +139,26 @@ static int read_sr(struct m25p *flash)
 }
 
 /*
+ * Read configuration register, returning its value in the
+ * location. Return the configuration register value.
+ * Returns negative if error occured.
+ */
+static int read_cr(struct m25p *flash)
+{
+	u8 code = OPCODE_RDCR;
+	int ret;
+	u8 val;
+
+	ret = spi_write_then_read(flash->spi, &code, 1, &val, 1);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev, "error %d reading CR\n", ret);
+		return ret;
+	}
+
+	return val;
+}
+
+/*
  * Write status register 1 byte
  * Returns negative if error occurred.
  */
@@ -220,6 +248,95 @@ static int wait_till_ready(struct m25p *flash)
 }
 
 /*
+ * Write status Register and configuration register with 2 bytes
+ * The first byte will be written to the status register, while the
+ * second byte will be written to the configuration register.
+ * Return negative if error occured.
+ */
+static int write_sr_cr(struct m25p *flash, u16 val)
+{
+	flash->command[0] = OPCODE_WRSR;
+	flash->command[1] = val & 0xff;
+	flash->command[2] = (val >> 8);
+
+	return spi_write(flash->spi, flash->command, 3);
+}
+
+static int macronix_quad_enable(struct m25p *flash)
+{
+	int ret, val;
+	u8 cmd[2];
+	cmd[0] = OPCODE_WRSR;
+
+	val = read_sr(flash);
+	cmd[1] = val | SR_QUAD_EN_MX;
+	write_enable(flash);
+
+	spi_write(flash->spi, &cmd, 2);
+
+	if (wait_till_ready(flash))
+		return 1;
+
+	ret = read_sr(flash);
+	if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+		dev_err(&flash->spi->dev,
+			"Macronix Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int spansion_quad_enable(struct m25p *flash)
+{
+	int ret;
+	int quad_en = CR_QUAD_EN_SPAN << 8;
+
+	write_enable(flash);
+
+	ret = write_sr_cr(flash, quad_en);
+	if (ret < 0) {
+		dev_err(&flash->spi->dev,
+			"error while writing configuration register");
+		return -EINVAL;
+	}
+
+	/* read back and check it */
+	ret = read_cr(flash);
+	if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+		dev_err(&flash->spi->dev,
+			"Spansion Quad bit not set");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static inline int set_quad_mode(struct m25p *flash, u32 jedec_id)
+{
+	int status;
+
+	switch (JEDEC_MFR(jedec_id)) {
+	case CFI_MFR_MACRONIX:
+		status = macronix_quad_enable(flash);
+		if (status) {
+			dev_err(&flash->spi->dev,
+				"Macronix quad-read not enabled");
+			return -EINVAL;
+		}
+		return status;
+	default:
+		status = spansion_quad_enable(flash);
+		if (status) {
+			dev_err(&flash->spi->dev,
+				"Spansion quad-read not enabled");
+			return -EINVAL;
+		}
+		return status;
+	}
+}
+
+/*
  * Erase the whole flash memory
  *
  * Returns 0 if successful, non-zero otherwise.
@@ -253,11 +370,24 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd)
 	cmd[4] = addr >> (flash->addr_width * 8 - 32);
 }
 
+/*
+ * Dummy Cycle calculation for fast and quad read.
+ * It can be used to support more commands with
+ * different dummy cycle requirement.
+ */
 static int m25p_cmdsz(struct m25p *flash)
 {
 	return 1 + flash->addr_width;
 }
 
+static inline int m25p80_dummy_cycles_read(struct m25p *flash)
+{
+	if (flash->quad_read || flash->fast_read)
+		return 1;
+
+	return 0;
+}
+
 /*
  * Erase one sector of flash memory at offset ``offset'' which is any
  * address within the sector which should be erased.
@@ -368,9 +498,10 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	memset(t, 0, (sizeof t));
 
 	t[0].tx_buf = flash->command;
-	t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0);
+	t[0].len = m25p_cmdsz(flash) + m25p80_dummy_cycles_read(flash);
 	spi_message_add_tail(&t[0], &m);
 
+	t[1].rx_nbits = flash->quad_read ? SPI_NBITS_QUAD : 1;
 	t[1].rx_buf = buf;
 	t[1].len = len;
 	spi_message_add_tail(&t[1], &m);
@@ -392,7 +523,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
 	spi_sync(flash->spi, &m);
 
 	*retlen = m.actual_length - m25p_cmdsz(flash) -
-			(flash->fast_read ? 1 : 0);
+			m25p80_dummy_cycles_read(flash);
 
 	mutex_unlock(&flash->lock);
 
@@ -698,6 +829,7 @@ struct flash_info {
 #define	SST_WRITE	0x04		/* use SST byte programming */
 #define	M25P_NO_FR	0x08		/* Can't do fastread */
 #define	SECT_4K_PMC	0x10		/* OPCODE_BE_4K_PMC works uniformly */
+#define	M25P80_QUAD_READ	0x20    /* Flash supports Quad Read */
 };
 
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@@ -775,7 +907,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) },
 
 	/* Micron */
 	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, 0) },
@@ -795,7 +927,7 @@ static const struct spi_device_id m25p_ids[] = {
 	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
 	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, M25P80_QUAD_READ) },
 	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
@@ -937,6 +1069,7 @@ static int m25p_probe(struct spi_device *spi)
 	unsigned			i;
 	struct mtd_part_parser_data	ppdata;
 	struct device_node *np = spi->dev.of_node;
+	int ret;
 
 	/* Platform data helps sort out which chip type we have, as
 	 * well as how this board partitions it.  If we don't have
@@ -1051,6 +1184,15 @@ static int m25p_probe(struct spi_device *spi)
 	flash->page_size = info->page_size;
 	flash->mtd.writebufsize = flash->page_size;
 
+	if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
+		ret = set_quad_mode(flash, info->jedec_id);
+		if (ret) {
+			dev_err(&flash->spi->dev, "quad mode not supported\n");
+			return ret;
+		}
+		flash->quad_read = true;
+	}
+
 	if (np)
 		/* If we were instantiated by DT, use it */
 		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
@@ -1063,7 +1205,9 @@ static int m25p_probe(struct spi_device *spi)
 		flash->fast_read = false;
 
 	/* Default commands */
-	if (flash->fast_read)
+	if (flash->quad_read)
+		flash->read_opcode = OPCODE_QUAD_READ;
+	else if (flash->fast_read)
 		flash->read_opcode = OPCODE_FAST_READ;
 	else
 		flash->read_opcode = OPCODE_NORM_READ;
@@ -1077,6 +1221,12 @@ static int m25p_probe(struct spi_device *spi)
 		flash->addr_width = 4;
 		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
 			/* Dedicated 4-byte command set */
+			if (flash->quad_read)
+				flash->read_opcode = OPCODE_QUAD_READ_4B;
+			else
+				flash->read_opcode = flash->fast_read ?
+					OPCODE_FAST_READ_4B :
+					OPCODE_NORM_READ_4B;
 			flash->read_opcode = flash->fast_read ?
 				OPCODE_FAST_READ_4B :
 				OPCODE_NORM_READ_4B;
-- 
1.7.1



From b32955 at freescale.com  Wed Oct 30 05:29:16 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 30 Oct 2013 17:29:16 +0800
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <5270D16C.6030802@freescale.com>

? 2013?10?30? 17:20, Sourav Poddar ??:
> @@ -1077,6 +1221,12 @@ static int m25p_probe(struct spi_device *spi)
>   		flash->addr_width = 4;
>   		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
>   			/* Dedicated 4-byte command set */
> +			if (flash->quad_read)
> +				flash->read_opcode = OPCODE_QUAD_READ_4B;
> +			else
> +				flash->read_opcode = flash->fast_read ?
> +					OPCODE_FAST_READ_4B :
> +					OPCODE_NORM_READ_4B;
>   			flash->read_opcode = flash->fast_read ?
>   				OPCODE_FAST_READ_4B :
>   				OPCODE_NORM_READ_4B;
you missed to remove these three lines above?

thanks
Huang Shijie



From sourav.poddar at ti.com  Wed Oct 30 05:32:59 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 15:02:59 +0530
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270D16C.6030802@freescale.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
 <5270D16C.6030802@freescale.com>
Message-ID: <5270D24B.5020800@ti.com>

Hi Huang,
On Wednesday 30 October 2013 02:59 PM, Huang Shijie wrote:
> ? 2013?10?30? 17:20, Sourav Poddar ??:
>> @@ -1077,6 +1221,12 @@ static int m25p_probe(struct spi_device *spi)
>>           flash->addr_width = 4;
>>           if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
>>               /* Dedicated 4-byte command set */
>> +            if (flash->quad_read)
>> +                flash->read_opcode = OPCODE_QUAD_READ_4B;
>> +            else
>> +                flash->read_opcode = flash->fast_read ?
>> +                    OPCODE_FAST_READ_4B :
>> +                    OPCODE_NORM_READ_4B;
>>               flash->read_opcode = flash->fast_read ?
>>                   OPCODE_FAST_READ_4B :
>>                   OPCODE_NORM_READ_4B;
> you missed to remove these three lines above?
My bad. its removed in my internal testing branch. While rebasing,
I made some error. I will update the patch and send v3.

Thanks Huang for your review. if you have any other comments, it will be 
great to
know, so that I can consolidate all in v3 and send.

Thanks!
>
> thanks
> Huang Shijie
>



From marex at denx.de  Tue Oct 29 14:24:27 2013
From: marex at denx.de (Marek Vasut)
Date: Tue, 29 Oct 2013 19:24:27 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526FEC7D.6060403@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <201310291808.58939.marex@denx.de> <526FEC7D.6060403@ti.com>
Message-ID: <201310291924.28110.marex@denx.de>

Dear Sourav Poddar,

[...]

> >>> This way, you can check if the SPI read failed and if so, handle it in
> >>> some way. The return value would only be valid if this function
> >>> returned 0.
> >> 
> >> I got this, but do you think its necessary to have two checks for
> >> verifying whether read passed. ?
> > 
> > Yes of course it is necessary, how else would you be able to tell if the
> > value is valid ? Sure, you can depend on negative integer here and on
> > the fact that the u8 will never be 32-bits wide (to produce a negative
> > integer when the return value is valid), but personally I think this is
> > error-prone as hell.
> > 
> >> If I go by your code above, after returning from above,
> >> check for return value for successful read
> >> and then check the respective bit set(SR_*). ?
> > 
> > Yes, you will be checking the bit in SR only if you are sure the value is
> > valid.
> 
> hmm..alrite I will do the cleanup and send v2.

Brian, does this make sense? I'd hate to misguide someone.

Best regards,
Marek Vasut


From ezequiel.garcia at free-electrons.com  Wed Oct 30 05:53:08 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 30 Oct 2013 06:53:08 -0300
Subject: [PATCH 1/1] mtd: nand: omap2: Fix device detection path
In-Reply-To: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <1383126788-27426-2-git-send-email-ezequiel.garcia@free-electrons.com>

Because the device bus can be 8-bit or 16-bit width, yet ONFI detection
cannot work in 16-bit mode, we need to set the NAND_BUSWIDTH_AUTO option
which allows proper initialization configuration.

Once the bus width is detected, nand_scan_ident() updates the nand_chip struct
'option' field to use the appropriate read/write functions and configure
the ECC engine.

Signed-off-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
---
 drivers/mtd/nand/omap2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index ec40b8d..c71206b 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1662,7 +1662,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	mtd->owner		= THIS_MODULE;
 	nand_chip		= &info->nand;
 	nand_chip->ecc.priv	= NULL;
-	nand_chip->options	|= NAND_SKIP_BBTSCAN;
+	nand_chip->options	|= NAND_SKIP_BBTSCAN | NAND_BUSWIDTH_AUTO;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
@@ -1708,7 +1708,6 @@ static int omap_nand_probe(struct platform_device *pdev)
 	}
 
 	/* scan NAND device connected to chip controller */
-	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;
 	if (nand_scan_ident(mtd, 1, NULL)) {
 		pr_err("nand device scan failed, may be bus-width mismatch\n");
 		err = -ENXIO;
-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Wed Oct 30 05:53:07 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 30 Oct 2013 06:53:07 -0300
Subject: [PATCH 0/1] Fix OMAP2 NAND ONFI device detection
Message-ID: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>

As it was discussed recently in the mailing list, the omap2-nand driver currently
has an issue preventing proper ONFI detection of 16-bit devices (other drivers
may suffer from this same issue).

In an attempt to address such issue, this patch uses NAND_BUSWIDTH_AUTO
(actually discarding any DT property) and leaves the bus width detection
to the NAND core code.

This has been tested in a Beaglebone black (AM335x) board with a 16-bit Micron
NAND device, both ONFI and array-based detections work fine:

[    1.560945] omap-gpmc 50000000.gpmc: GPMC revision 6.0
[    1.569328] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron MT29F4G16ABADAH4)
[    1.577853] NAND device: 512MiB, SLC, page size: 2048, OOB size: 64
[    1.584448] nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme
[    1.591772] 8 ofpart partitions found on MTD device omap2-nand.0
[    1.598171] Creating 8 MTD partitions on "omap2-nand.0":
[    1.603797] 0x000000000000-0x000000020000 : "SPL1"
[    1.612926] 0x000000020000-0x000000040000 : "SPL2"
[    1.620112] 0x000000040000-0x000000060000 : "SPL3"
[    1.627192] 0x000000060000-0x000000080000 : "SPL4"
[    1.634205] 0x000000080000-0x000000260000 : "U-boot"
[    1.642708] 0x000000260000-0x000000280000 : "environment"
[    1.650410] 0x000000280000-0x000000780000 : "Kernel"
[    1.661828] 0x000000780000-0x000010000000 : "File-System"

Also, a quick run of nandtest ends successfully:

# nandtest /dev/mtd6
ECC corrections: 0
ECC failures   : 0
Bad blocks     : 0
BBT blocks     : 0
004e0000: checking...
Finished pass 1 successfully

This time I've decided to submit this patch alone, so we can focus
the discussion on this issue. The other cleanups can wait.

AFAICS, the remaining questions are:

 1. Does this work in the 8-bit case?
 (I'm not able to test such case for lack of hardware)

 2. Do we want to re-configure the GPMC one the NAND core detects the
    device bus width?

Regarding this last question, and as I've exposed in the discussion with Pekon
about this [1], IMO, doing so is a bad design choice. It's not the NAND
driver's task to fix illed-prepared device-tree's or a badly configured memory
controller (GPMC).

[1] http://www.mail-archive.com/linux-omap at vger.kernel.org/msg97760.html

Ezequiel Garcia (1):
  mtd: nand: omap2: Fix device detection path

 drivers/mtd/nand/omap2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

-- 
1.8.1.5



From ezequiel.garcia at free-electrons.com  Wed Oct 30 05:56:41 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 30 Oct 2013 06:56:41 -0300
Subject: [PATCH -next] mtd: remove duplicated include from mtdcore.c
In-Reply-To: <CAPgLHd8=fLjqnKEoTB2C+7R=Nz7bdV0D5ttO29em=P8nX-Tvag@mail.gmail.com>
References: <CAPgLHd8=fLjqnKEoTB2C+7R=Nz7bdV0D5ttO29em=P8nX-Tvag@mail.gmail.com>
Message-ID: <20131030095640.GC2453@localhost>

On Wed, Oct 30, 2013 at 01:34:22PM +0800, Wei Yongjun wrote:
> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> 
> Remove duplicated include.
> 
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> ---
>  drivers/mtd/mtdcore.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> index 7189089..92311a5 100644
> --- a/drivers/mtd/mtdcore.c
> +++ b/drivers/mtd/mtdcore.c
> @@ -37,7 +37,6 @@
>  #include <linux/backing-dev.h>
>  #include <linux/gfp.h>
>  #include <linux/slab.h>
> -#include <linux/major.h>
>  
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/partitions.h>
> 
> 

Acked-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

Ooops.. sorry about that. This was introduced by me in this one:

commit 40d1b2e461f28c4add582ef7ca8ed9f16f6b5add
Author: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>
Date:   Sun Oct 13 18:05:23 2013 -0300

mtd: Move major number definitions to major.h
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From marex at denx.de  Wed Oct 30 06:11:54 2013
From: marex at denx.de (Marek Vasut)
Date: Wed, 30 Oct 2013 11:11:54 +0100
Subject: [PATCH] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <526FFFA0.8040800@ti.com>
References: <1382693145-15750-1-git-send-email-sourav.poddar@ti.com>
 <526FEC7D.6060403@ti.com> <526FFFA0.8040800@ti.com>
Message-ID: <201310301111.54613.marex@denx.de>

Dear Sourav Poddar,

> On Tuesday 29 October 2013 10:42 PM, Sourav Poddar wrote:
> > On Tuesday 29 October 2013 10:38 PM, Marek Vasut wrote:
> >> Dear Sourav Poddar,
> >> 
> >>> On Tuesday 29 October 2013 08:57 PM, Marek Vasut wrote:
> >>>> Dear Sourav Poddar,
> >>>> 
> >>>>> Dear Marek Vasut,
> >>>>> 
> >>>>> On Tuesday 29 October 2013 07:31 PM, Marek Vasut wrote:
> >>>>>> Dear Sourav Poddar,
> >>>>>> 
> >>>>>>> Hi,
> >>>>>>> 
> >>>>>>> On Sunday 27 October 2013 10:15 PM, Marek Vasut wrote:
> >>>>>>>> Dear Sourav Poddar,
> >>>>>>>> 
> >>>>>>>> [...]
> >>>>>>>> 
> >>>>>>>>> +static int macronix_quad_enable(struct m25p *flash)
> >>>>>>>>> +{
> >>>>>>>>> +    int ret, val;
> >>>>>>>>> +    u8 cmd[2];
> >>>>>>>>> +    cmd[0] = OPCODE_WRSR;
> >>>>>>>>> +
> >>>>>>>>> +    val = read_sr(flash);
> >>>>>>>>> +    cmd[1] = val | SR_QUAD_EN_MX;
> >>>>>>>>> +    write_enable(flash);
> >>>>>>>>> +
> >>>>>>>>> +    spi_write(flash->spi,&cmd, 2);
> >>>>>>>>> +
> >>>>>>>>> +    if (wait_till_ready(flash))
> >>>>>>>>> +        return 1;
> >>>>>>>>> +
> >>>>>>>>> +    ret = read_sr(flash);
> >>>>>>>> 
> >>>>>>>> Maybe read_sr() and read_cr() shall be fixed to return retval only
> >>>>>>>> and the val shall be passed to them as an argument pointer?
> >>>>>>>> Aka. ret
> >>>>>>>> = read_sr(flash,&val);
> >>>>>>>> 
> >>>>>>>> That way, this dangerous construct below could become:
> >>>>>>>> 
> >>>>>>>> if (!(val&     SR_....)) {
> >>>>>>>> 
> >>>>>>>>     dev_err();
> >>>>>>>>     ret = -EINVAL;
> >>>>>>>> 
> >>>>>>>> }
> >>>>>>>> 
> >>>>>>>> return ret;
> >>>>>>> 
> >>>>>>> I was trying to work on it and realise, we dont need to pass val
> >>>>>>> directly. We can continue returning the val and can still
> >>>>>>> cleanup the
> >>>>>>> below code as u suggetsed above.
> >>>>>>> if (!(ret&    SR_....)) {
> >>>>>>> 
> >>>>>>>         dev_err();
> >>>>>>>         ret = -EINVAL;
> >>>>>>> 
> >>>>>>> }
> >>>>>> 
> >>>>>> Uh oh, no. This doesn't seem right. I'd like to be able to clearly
> >>>>>> check if the function failed to read the register altogether OR if
> >>>>>> not, check the returned value of the register. Mixing these two
> >>>>>> together won't do us good. But maybe I just fail to understand your
> >>>>>> proposal, if so, then I appologize.
> >>>>> 
> >>>>> Yes, what I am trying to propose is to eliminate the return error
> >>>>> check.
> >>>> 
> >>>> But we want to be able to check if there is a failure :)
> >>>> 
> >>>>> The check whether register read has happened correctly is embedded in
> >>>>> read_sr/read_cr function itself.
> >>>>> 
> >>>>>            if (retval<   0) {
> >>>>>            
> >>>>>                    dev_err(&flash->spi->dev, "error %d reading SR\n",
> >>>>>                    
> >>>>>                                    (int) retval);
> >>>>>                    
> >>>>>                    return retval;
> >>>>>            
> >>>>>            }
> >>>>> 
> >>>>> Same goes for read_cr.
> >>>>> So, if the above condition is not hit, we simply return the read
> >>>>> value
> >>>>> and check it with the respective bits.
> >>>> 
> >>>> Look here:
> >>>>    107 static int read_sr(struct m25p *flash)
> >>>>    108 {
> >>>>    109         ssize_t retval;
> >>>>    110         u8 code = OPCODE_RDSR;
> >>>>    111         u8 val;
> >>>>    112
> >>>>    113         retval = spi_write_then_read(flash->spi,&code,
> >>>> 
> >>>> 1,&val, 1);
> >>>> 
> >>>>    114
> >>>>    115         if (retval<   0) {
> >>>>    116                 dev_err(&flash->spi->dev, "error %d reading
> >>>> 
> >>>> SR\n",
> >>>> 
> >>>>    117                                 (int) retval);
> >>>>    118                 return retval;
> >>>> 
> >>>> here you return error value IFF spi_write_then_read() fails for some
> >>>> reason.
> >>>> 
> >>>>    119         }
> >>>>    120
> >>>>    121         return val;
> >>>> 
> >>>> here you return actual value of the register.
> >>>> 
> >>>>    122 }
> >>>> 
> >>>> This is how I'd change the function to make it less error-prone:
> >>>> 
> >>>> *107 static int read_sr(struct m25p *flash, u8 *rval)
> >>>> 
> >>>>    108 {
> >>>>    109         ssize_t retval;
> >>>>    110         u8 code = OPCODE_RDSR;
> >>>>    111         u8 val;
> >>>>    112
> >>>>    113         retval = spi_write_then_read(flash->spi,&code,
> >>>> 
> >>>> 1,&val, 1);
> >>>> 
> >>>>    114
> >>>>    115         if (retval<   0) {
> >>>>    116                 dev_err(&flash->spi->dev, "error %d reading
> >>>> 
> >>>> SR\n",
> >>>> 
> >>>>    117                                 (int) retval);
> >>>>    118                 return retval;
> >>>>    119         }
> >>>> 
> >>>> *120         *rval = val;
> >>>> *121         return 0;
> >>>> 
> >>>>    122 }
> >>>> 
> >>>> This way, you can check if the SPI read failed and if so, handle it in
> >>>> some way. The return value would only be valid if this function
> >>>> returned
> >>>> 0.
> >>> 
> >>> I got this, but do you think its necessary to have two checks for
> >>> verifying
> >>> whether read passed. ?
> >> 
> >> Yes of course it is necessary, how else would you be able to tell if
> >> the value
> >> is valid ? Sure, you can depend on negative integer here and on the
> >> fact that
> >> the u8 will never be 32-bits wide (to produce a negative integer when
> >> the return
> >> value is valid), but personally I think this is error-prone as hell.
> >> 
> >>> If I go by your code above, after returning from above,
> >>> check for return value for successful read
> >>> and then check the respective bit set(SR_*). ?
> >> 
> >> Yes, you will be checking the bit in SR only if you are sure the
> >> value is valid.
> > 
> > hmm..alrite I will do the cleanup and send v2.
> 
> I think it will be better to take the above recommended cleanup as a
> seperate patch
> on top of $subject patch?

Separate patch is OK, but I think it's better to put it before this series to 
not spread this bad practice further.

Again, I will wave at Brian to stop my possible misguidance ASAP here.


From b32955 at freescale.com  Wed Oct 30 06:18:52 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 30 Oct 2013 18:18:52 +0800
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <5270DD0C.2090902@freescale.com>

? 2013?10?30? 17:20, Sourav Poddar ??:
> @@ -1051,6 +1184,15 @@ static int m25p_probe(struct spi_device *spi)
>   	flash->page_size = info->page_size;
>   	flash->mtd.writebufsize = flash->page_size;
>
> +	if (spi->mode&  SPI_RX_QUAD&&  info->flags&  M25P80_QUAD_READ) {
> +		ret = set_quad_mode(flash, info->jedec_id);
> +		if (ret) {
> +			dev_err(&flash->spi->dev, "quad mode not supported\n");
> +			return ret;
> +		}
> +		flash->quad_read = true;
> +	}
Do we really need the M25P80_QUAD_READ?

Some NOR flash can supports both the QUAD read and DDR QUAD read, while 
some NOR flash only supports the
QUAD read.

when we try to add the DDR QUAD READ support, should we add another 
flag, such as M25P80_DDR_QUAD_READ?

Add Mark for this email.

I think you'd better CC this patch to the SPI maillist & Mark,.


thanks
Huang Shijie






From sourav.poddar at ti.com  Wed Oct 30 06:19:26 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Wed, 30 Oct 2013 15:49:26 +0530
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270DD0C.2090902@freescale.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
 <5270DD0C.2090902@freescale.com>
Message-ID: <5270DD2E.1010805@ti.com>

On Wednesday 30 October 2013 03:48 PM, Huang Shijie wrote:
> ? 2013?10?30? 17:20, Sourav Poddar ??:
>> @@ -1051,6 +1184,15 @@ static int m25p_probe(struct spi_device *spi)
>>       flash->page_size = info->page_size;
>>       flash->mtd.writebufsize = flash->page_size;
>>
>> +    if (spi->mode&  SPI_RX_QUAD&&  info->flags&  M25P80_QUAD_READ) {
>> +        ret = set_quad_mode(flash, info->jedec_id);
>> +        if (ret) {
>> +            dev_err(&flash->spi->dev, "quad mode not supported\n");
>> +            return ret;
>> +        }
>> +        flash->quad_read = true;
>> +    }
> Do we really need the M25P80_QUAD_READ?
>
This is what we allign initially that its correct to  get this 
information through flash itself rather than dt.
> Some NOR flash can supports both the QUAD read and DDR QUAD read, 
> while some NOR flash only supports the
> QUAD read.
>
> when we try to add the DDR QUAD READ support, should we add another 
> flag, such as M25P80_DDR_QUAD_READ?
>
I suppose we need to.
> Add Mark for this email.
>
> I think you'd better CC this patch to the SPI maillist & Mark,.
>
>
> thanks
> Huang Shijie
>
>
>
>
>
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/



From b32955 at freescale.com  Wed Oct 30 06:25:06 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Wed, 30 Oct 2013 18:25:06 +0800
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270DD2E.1010805@ti.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
 <5270DD0C.2090902@freescale.com> <5270DD2E.1010805@ti.com>
Message-ID: <5270DE82.9020603@freescale.com>

? 2013?10?30? 18:19, Sourav Poddar ??:
> This is what we allign initially that its correct to  get this 
> information through flash itself rather than dt. 
okay. got it.



Huang Shijie



From tomi.valkeinen at ti.com  Wed Oct 30 06:59:08 2013
From: tomi.valkeinen at ti.com (Tomi Valkeinen)
Date: Wed, 30 Oct 2013 12:59:08 +0200
Subject: [PATCH 00/19] Enable various Renesas drivers on all ARM platforms
In-Reply-To: <20131030000501.GE21262@verge.net.au>
References: <1383004027-25036-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
 <1577821.Q7gttkPE2J@avalon> <20131029172331.GA20251@sirena.org.uk>
 <1422562.0L87CDt5Gd@avalon> <20131029175834.GD20251@sirena.org.uk>
 <20131030000501.GE21262@verge.net.au>
Message-ID: <5270E67C.1030307@ti.com>

On 2013-10-30 02:05, Simon Horman wrote:
> On Tue, Oct 29, 2013 at 10:58:34AM -0700, Mark Brown wrote:
>> On Tue, Oct 29, 2013 at 06:29:59PM +0100, Laurent Pinchart wrote:
>>> On Tuesday 29 October 2013 10:23:31 Mark Brown wrote:
>>>> On Tue, Oct 29, 2013 at 06:05:53PM +0100, Laurent Pinchart wrote:
>>>>> The first one is that I can't compile-test all those drivers on all
>>>>> architectures. The spi-sh-msiof driver, for instance, uses
>>>>> io(read|write)(16|
>>
>>>> Which architectures are these and is there not a symbol we can depend on
>>>> for them?
>>
>>> arch/cris for instance. We can use readl/writel instead (maybe it would be 
>>> time to rationalize and document the I/O accessors across all architectures, 
>>> but that's another topic).
>>
>> It'd certainly be sensible, or adding a config option to depend on if
>> you rely on these functions.
>>
>>> My point is that there might be other issues that I won't be able to easily 
>>> catch. This would break compilation for everybody for no reason, as the 
>>> drivers are useless on non-SuperH, non-ARM platforms. That's why I believe 
>>> COMPILE_TEST would be a better option as a first step.
>>
>> Yes, it would - please do that.  Note that it won't stop anyone running
>> into build issues on other architectures though, it's just about
>> stopping Kconfig noise.
> 
> FWIW, I am happy with using COMPILE_TEST for this series.

I'd also go for COMPILE_TEST. I once enabled omapdss and omapfb to be
compilable without any extra dependencies, and Linus wasn't fond of
getting asked if he wants to compile omapfb or not...

 Tomi


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 901 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20131030/b75b2a9a/attachment.sig>

From marex at denx.de  Wed Oct 30 09:38:24 2013
From: marex at denx.de (Marek Vasut)
Date: Wed, 30 Oct 2013 14:38:24 +0100
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5270DE82.9020603@freescale.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
 <5270DD2E.1010805@ti.com> <5270DE82.9020603@freescale.com>
Message-ID: <201310301438.24441.marex@denx.de>

Dear Huang Shijie,

> ? 2013?10?30? 18:19, Sourav Poddar ??:
> > This is what we allign initially that its correct to  get this
> > information through flash itself rather than dt.
> 
> okay. got it.

We certainly need this to operate as such:

- The SPI NOR driver knows what the SPI NOR flash can do (if it can do fast 
read, quad read, ddr read ...)
- The SPI bus driver knows what types of transfer it can support

The SPI NOR driver shall then negotiate the best transfer option and use it. So 
yes, we need flags to specify what each SPI NOR can do.

Best regards,
Marek Vasut


From computersforpeace at gmail.com  Wed Oct 30 15:14:14 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 15:14:14 -0400
Subject: [PATCH 0/1] Fix OMAP2 NAND ONFI device detection
In-Reply-To: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131030191414.GA16668@norris.computersforpeace.net>

Hi,

On Wed, Oct 30, 2013 at 06:53:07AM -0300, Ezequiel Garcia wrote:
> As it was discussed recently in the mailing list, the omap2-nand driver currently
> has an issue preventing proper ONFI detection of 16-bit devices (other drivers
> may suffer from this same issue).

First of all, thanks for clearly separating this discussion to its own
patch. It is an interesting issue by itself (without tying it up with
other driver-specific issues), and I think it has something useful to
teach other drivers, which may mostly be dodging issues with x16
devices.

> In an attempt to address such issue, this patch uses NAND_BUSWIDTH_AUTO
> (actually discarding any DT property) and leaves the bus width detection
> to the NAND core code.
> 
> This has been tested in a Beaglebone black (AM335x) board with a 16-bit Micron
> NAND device, both ONFI and array-based detections work fine:
> 
> [    1.560945] omap-gpmc 50000000.gpmc: GPMC revision 6.0
> [    1.569328] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron MT29F4G16ABADAH4)
> [    1.577853] NAND device: 512MiB, SLC, page size: 2048, OOB size: 64
> [    1.584448] nand: using OMAP_ECC_BCH8_CODE_HW ECC scheme
> [    1.591772] 8 ofpart partitions found on MTD device omap2-nand.0
> [    1.598171] Creating 8 MTD partitions on "omap2-nand.0":
> [    1.603797] 0x000000000000-0x000000020000 : "SPL1"
> [    1.612926] 0x000000020000-0x000000040000 : "SPL2"
> [    1.620112] 0x000000040000-0x000000060000 : "SPL3"
> [    1.627192] 0x000000060000-0x000000080000 : "SPL4"
> [    1.634205] 0x000000080000-0x000000260000 : "U-boot"
> [    1.642708] 0x000000260000-0x000000280000 : "environment"
> [    1.650410] 0x000000280000-0x000000780000 : "Kernel"
> [    1.661828] 0x000000780000-0x000010000000 : "File-System"
> 
> Also, a quick run of nandtest ends successfully:
> 
> # nandtest /dev/mtd6
> ECC corrections: 0
> ECC failures   : 0
> Bad blocks     : 0
> BBT blocks     : 0
> 004e0000: checking...
> Finished pass 1 successfully

I suspected this was the case (in agreement with your comments on
previous threads): that BUSWIDTH_AUTO will discover the correct buswidth
*AND* will handle initial ONFI requests correctly (i.e., initially in x8
"mode", then switching to x16 callbacks as appropriate).

I do have one curiosity here: omap2.c looks like it's essentially
defaulting to the NAND_OMAP_POLLED callbacks during nand_scan_ident(),
since omap2.c only initializes the read_buf callback after
nand_scan_ident(). Is this ever a problem? Or should omap2.c be
initializing its callbacks both before and after nand_scan_ident()
(similar to how nand_base calls nand_set_defaults() twice for the AUTO
case)?

What value do you use for "ti,nand-xfer-type" in your BeagleBone device
tree? Is the xfer type a hardware requirement, or just a software
configuration? IOW, does the hardware care if I simply use POLLED, even
temporarily? (A potential side issue: does "ti,nand-xfer-type" even
belong in the device tree, if it is not actually a hardware property?)

> This time I've decided to submit this patch alone, so we can focus
> the discussion on this issue. The other cleanups can wait.
> 
> AFAICS, the remaining questions are:
> 
>  1. Does this work in the 8-bit case?
>  (I'm not able to test such case for lack of hardware)

I'm not sure, of course, but I don't see why not. It's more likely to
break for x16 than it is for x8.

>  2. Do we want to re-configure the GPMC one the NAND core detects the
>     device bus width?

I'm not quite sure here, as I don't know if I know enough about the GPMC
to give an educated response here. Additionally, I'm not quite sure how
"re-configurable" GPMC really is. It seems like we would be restricted
physically if GPMC is hooked up as x8 for an x16 NAND (there are not
enough pins connected). So even if we detect the NAND, it cannot
function. I'm not sure about the reverse.

Now, this returns me to my rejection of Pekon's patch here:

  http://lists.infradead.org/pipermail/linux-mtd/2013-October/049154.html

(This patch addresses the question of checking the GPMC configuration,
not correcting it.)

I'll admit that I was underinformed regarding the need for this type of
patch. Since that time, I am less sure of my criticism. But really, I
just have more questions now.

Does the GPMC intrinsically (physically; according to its pin
configuration) restrict an attached device (e.g., NAND) to use x16 or
x8? Or does it simply specify a maximum data width that is wired up?
(I'm presuming that you could wire an x8 device to an x16 interface and
just leave the upper 8 unconnected...) Or is there some third option?

The DT entry says:

  gpmc,device-width     Total width of device(s) connected to a GPMC
                        chip-select in bytes. The GPMC supports 8-bit
                        and 16-bit devices and so this property must be
                        1 or 2.

So, this *sounds* like it specifies the exact width. But as I read it,
this property could more optimally be specified as the *maximum*
width...

> Regarding this last question, and as I've exposed in the discussion with Pekon
> about this [1], IMO, doing so is a bad design choice. It's not the NAND
> driver's task to fix illed-prepared device-tree's or a badly configured memory
> controller (GPMC).
> 
> [1] http://www.mail-archive.com/linux-omap at vger.kernel.org/msg97760.html

Brian


From pekon at ti.com  Wed Oct 30 17:18:53 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 30 Oct 2013 21:18:53 +0000
Subject: [PATCH 0/1] Fix OMAP2 NAND ONFI device detection
In-Reply-To: <20131030191414.GA16668@norris.computersforpeace.net>
References: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131030191414.GA16668@norris.computersforpeace.net>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2D41D@DBDE04.ent.ti.com>

Hi Brian, Ezequiel Garcia,

Some replies to your queries...

> From: Brian Norris [mailto:computersforpeace at gmail.com]
> > On Wed, Oct 30, 2013 at 06:53:07AM -0300, Ezequiel Garcia wrote:

[...]

> I do have one curiosity here: omap2.c looks like it's essentially
> defaulting to the NAND_OMAP_POLLED callbacks during nand_scan_ident(),
> since omap2.c only initializes the read_buf callback after
> nand_scan_ident(). Is this ever a problem? Or should omap2.c be
> initializing its callbacks both before and after nand_scan_ident()
> (similar to how nand_base calls nand_set_defaults() twice for the AUTO
> case)?
> 
There is no issue if _default_ functions present in nand_base.c
are used for chip->read_byte() or chip->read_buf() while probing the device.
The different callbacks defined in omap2.c like
- omap_read_buf()
- omap_read_buf_pref()
- omap_read_buf_dma_pref()
- omap_read_buf_irq_pref()
Above are alternatives for having better throughput in different use-cases.
These are not tied to hardware. So it's okay if these callbacks are assigned
post nand_scan_ident().


> What value do you use for "ti,nand-xfer-type" in your BeagleBone device
> tree? Is the xfer type a hardware requirement, or just a software
> configuration? IOW, does the hardware care if I simply use POLLED, even
> temporarily? (A potential side issue: does "ti,nand-xfer-type" even
> belong in the device tree, if it is not actually a hardware property?)
> 
DMA and IRQ based callbacks have better throughput numbers than
POLLED ones. Though its not related to hardware, but as it's there in DT
now so we should maintain it. Also considering that:
- some older platforms might not support xx_dma_pref().
- some related pieces of information (like IRQ number, etc) comes from DT.
It was added as part of following patch..
http://www.spinics.net/lists/linux-omap/msg90250.html


> > This time I've decided to submit this patch alone, so we can focus
> > the discussion on this issue. The other cleanups can wait.
> >
> > AFAICS, the remaining questions are:
> >
> >  1. Does this work in the 8-bit case?
> >  (I'm not able to test such case for lack of hardware)
> 
> I'm not sure, of course, but I don't see why not. It's more likely to
> break for x16 than it is for x8.
> 
Another question here is ..
The above patch assumes that user has configured GPMC bus-width
correctly, so if user is already providing GPMC bus-width information
via DT, then do we really need to detect NAND device bus-width again
using NAND_BUSWIDTH_AUTO ?
 

> >  2. Do we want to re-configure the GPMC one the NAND core detects the
> >     device bus width?
> 
> I'm not quite sure here, as I don't know if I know enough about the GPMC
> to give an educated response here. Additionally, I'm not quite sure how
> "re-configurable" GPMC really is. It seems like we would be restricted
> physically if GPMC is hooked up as x8 for an x16 NAND (there are not
> enough pins connected). So even if we detect the NAND, it cannot
> function. I'm not sure about the reverse.
> 
> Now, this returns me to my rejection of Pekon's patch here:
> 
>   http://lists.infradead.org/pipermail/linux-mtd/2013-October/049154.html
> 
> (This patch addresses the question of checking the GPMC configuration,
> not correcting it.)
> 
> I'll admit that I was underinformed regarding the need for this type of
> patch. Since that time, I am less sure of my criticism. But really, I
> just have more questions now.
> 
> Does the GPMC intrinsically (physically; according to its pin
> configuration) restrict an attached device (e.g., NAND) to use x16 or
> x8?
Yes.. 

>  Or does it simply specify a maximum data width that is wired up?
> (I'm presuming that you could wire an x8 device to an x16 interface and
> just leave the upper 8 unconnected...) Or is there some third option?
> 
GPMC engine uses bus-width info to drive its data-lines.
- If GPMC is configured as x8, then it will only perform I/O on D0.. D7,
   even if all D0 .. D15 were wired on board.
- If GPMC is configured as x16, then it will perform I/O on D0.. D15,
   even if only D0 .. D7 were wired on board. There by reading 0x0 or
   garbage on D8 .. D15 lines.

This does not affect the probe, because chip->read_byte() would return
only single byte whether it's a x8 device or x16 device. So READID_CMD
works fine and you can read maf_id and dev_id. And based on that
device parameters can be looked from nand_flash_id[].
However when it comes to reading or writing complete page, then the
mismatch between GPMC configuration and actual NAND device
bus-width is seen, because there chip->read_buf() or chip->write_buf()
is used.


> The DT entry says:
> 
>   gpmc,device-width     Total width of device(s) connected to a GPMC
>                         chip-select in bytes. The GPMC supports 8-bit
>                         and 16-bit devices and so this property must be
>                         1 or 2.
> 
> So, this *sounds* like it specifies the exact width. But as I read it,
> this property could more optimally be specified as the *maximum*
> width...
> 
Yes, its exact width..


> > Regarding this last question, and as I've exposed in the discussion with
> Pekon
> > about this [1], IMO, doing so is a bad design choice. It's not the NAND
> > driver's task to fix illed-prepared device-tree's or a badly configured
> memory
> > controller (GPMC).
> >
> > [1] http://www.mail-archive.com/linux-omap at vger.kernel.org/msg97760.html
> 
> Brian


with regards, pekon


From pekon at ti.com  Wed Oct 30 17:30:24 2013
From: pekon at ti.com (Gupta, Pekon)
Date: Wed, 30 Oct 2013 21:30:24 +0000
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up of
 supported ECC schemes
In-Reply-To: <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <20131024135258.GC9958@localhost>
 <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>
Message-ID: <20980858CB6D3A4BAE95CA194937D5E73EA2D43E@DBDE04.ent.ti.com>

> From: Brian Norris [mailto:computersforpeace at gmail.com]
[...]

> I agree with Ezequiel's thoughts, since the excessive amount of noise
> in this patch series has delayed it significantly. But at this point,
> I think it has stabilized; we have reviews from the DT folks (thanks
> guys; please comment if you have an official "ack" to give), and I
> think we've retained backwards compatibility properly; I've combed
> through it a few times over the months; we have a third-party tester;
> and at this point, I'm sure we're all sick of this.
> 
> So, without further delay: pushed all patches except path 8 to l2-mtd.git.
> 
Thanks much ..
I'll ensure that my next series are more logically aligned.


> Tony, you mentioned the DTS update in patch 8 going in via an ARM
> tree? This patch is not urgent, and it should probably wait until we
> know what release the rest of the series makes it into. This may
> depend on David Woodhouse's recommendation, but I'm not sure this
> series will have enough time baking in linux-next before entering
> mainline in 3.13 (the merge window is approaching).
> 
> Pekon/Ezequiel/others: please feel free to send any follow up cleanups
> for this driver. I'll take a look at what Ezequiel has already sent
> out and see if it's still applicable on top.
> 
Yes, I have other pending series, which I'll resend after rebasing on
this v11. But those are limited to internal NAND driver clean-up only
And do not touch DT or any other dependent driver.


with regards, pekon


From computersforpeace at gmail.com  Wed Oct 30 17:37:41 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 17:37:41 -0400
Subject: [PATCH -next] mtd: remove duplicated include from mtdcore.c
In-Reply-To: <20131030095640.GC2453@localhost>
References: <CAPgLHd8=fLjqnKEoTB2C+7R=Nz7bdV0D5ttO29em=P8nX-Tvag@mail.gmail.com>
 <20131030095640.GC2453@localhost>
Message-ID: <20131030213741.GA20059@norris.computersforpeace.net>

On Wed, Oct 30, 2013 at 06:56:41AM -0300, Ezequiel Garcia wrote:
> On Wed, Oct 30, 2013 at 01:34:22PM +0800, Wei Yongjun wrote:
> > From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> > 
> > Remove duplicated include.
> > 
> > Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> > ---
> >  drivers/mtd/mtdcore.c | 1 -
> >  1 file changed, 1 deletion(-)
> > 
> > diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
> > index 7189089..92311a5 100644
> > --- a/drivers/mtd/mtdcore.c
> > +++ b/drivers/mtd/mtdcore.c
> > @@ -37,7 +37,6 @@
> >  #include <linux/backing-dev.h>
> >  #include <linux/gfp.h>
> >  #include <linux/slab.h>
> > -#include <linux/major.h>
> >  
> >  #include <linux/mtd/mtd.h>
> >  #include <linux/mtd/partitions.h>
> > 
> > 
> 
> Acked-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

Pushed to l2-mtd.git, thanks Wei! It probably could just be squashed
into the original patch, but I'm not sure it's actually worth the
rebase.

Brian


From computersforpeace at gmail.com  Wed Oct 30 17:58:36 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 17:58:36 -0400
Subject: [PATCH 1/1] mtd: mxc_nand: Include linux/of.h header
In-Reply-To: <1382093195-31929-1-git-send-email-sachin.kamat@linaro.org>
References: <1382093195-31929-1-git-send-email-sachin.kamat@linaro.org>
Message-ID: <20131030215836.GB20059@norris.computersforpeace.net>

On Fri, Oct 18, 2013 at 04:16:35PM +0530, Sachin Kamat wrote:
> 'of_match_ptr' is defined in linux/of.h. Include it explicitly to
> avoid build breakage in the future.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat at linaro.org>
> ---
>  drivers/mtd/nand/mxc_nand.c |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index ce8242b..1037755 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -32,6 +32,7 @@
>  #include <linux/io.h>
>  #include <linux/irq.h>
>  #include <linux/completion.h>
> +#include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/of_mtd.h>

I'm not really sure this is all that necessary (are of_device.h or
of_mtd.h ever not going to include the appropriate of.h header?), but
since we have the patch (and I see that you've been spamming around the
other subsystems with similar patches)...

Applied to l2-mtd.git.

Brian


From computersforpeace at gmail.com  Wed Oct 30 18:02:57 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 18:02:57 -0400
Subject: [PATCH v3 00/10] About the SLC/MLC
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA297AE@DBDE04.ent.ti.com>
References: <1377509808-29363-1-git-send-email-b32955@freescale.com>
 <20130826144153.568f2b1c@skate> <20130827033020.GA2182@gmail.com>
 <20980858CB6D3A4BAE95CA194937D5E73EA297AE@DBDE04.ent.ti.com>
Message-ID: <20131030220257.GC20059@norris.computersforpeace.net>

Late response, but better late than never?

On Tue, Oct 22, 2013 at 05:11:37AM +0000, Pekon Gupta wrote:
> > From:  Huang Shijie
> > On Mon, Aug 26, 2013 at 02:41:53PM +0200, Thomas Petazzoni wrote:
> > > Dear Huang Shijie,
> > >
> > > On Mon, 26 Aug 2013 17:36:38 +0800, Huang Shijie wrote:
> > > > In current mtd code, the MTD_NANDFLASH is used to represent both the
> > > > SLC nand MLC(including the TLC). But we already have the
> > MTD_MLCNANDFLASH
> > > > to stand for the MLC. What is worse is that the JFFS2 may run on the MLC
> > > > nand with current code. For the reason of READ/WRITE disturbance, the
> > JFFS2
> > > > should runs on the SLC only,
> > >
> > > Pardon the probably very silly question, but would you mind giving more
> > > details about why JFFS2 is not appropriate on MLC flashes? Is there
> > > anything that UBI/UBIFS does that JFFS2 isn't doing to take into
> > > account read/write disturbance?
> > I try to explain it.
> > 
> > For the UBIFS, it will writes the page(including the oob) only one time;
> > but for jffs2, it may writes the page(including the oob) twice, one for the
> > marker, one for the real data.
> > 
> > For the MLC, the write disturbance will cause some bitflips in this
> > page. Since you write a page twice, so in the jffs2, you will meet
> > uncorrectable
> > ECC error.
> > 
> But, doesn't JFFS2 checks for the blank page before second-write of data ?
> UBI does it here..
> File: $KERNEL/drivers/mtd/ubi/io.c
> @@ubi_io_write (... )
> [...]
> 	err = ubi_self_check_all_ff(ubi, pnum, offset, len);
> 
> So, isn't it better to add this check in JFFS2 code so that its more
> bit-flips tolerant ?
> This way bit-flips caused by first write to OOB (cleanmarker) would be
> caught before using that page for data write. And so MLC should also be
> good for JFFS2..

Sorry, no. MLC (and some SLC these days, actually) has a fundamental
limitation that it can only be programmed once per erase-cycle. This
measure is abbreviated as "NOP" (Number Of Partial-programs?), and for
MLC, NOP=1.

So trying to support the JFFS2 model of double-programming a page is
simply counter-productive when NOP=1.

Brian


From computersforpeace at gmail.com  Wed Oct 30 19:19:31 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 19:19:31 -0400
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
Message-ID: <20131030231930.GD20059@norris.computersforpeace.net>

On Wed, Oct 30, 2013 at 02:50:02PM +0530, Sourav Poddar wrote:
> Some flash also support quad read mode.
> Adding support for adding quad mode in m25p80
> for spansion and macronix flash.
> 
> Signed-off-by: Sourav Poddar <sourav.poddar at ti.com>
> ---
> Rebase this on latest l2mtd.
> v1->v2:
> Small dev_err message fix to make it
> mode appropriate.
> v1: http://patchwork.ozlabs.org/patch/286109/
> 
> There is one cleanup suggestion from Marek Vasut on read_sr
> value. I will take that up as a seperate patch, once this 
> patch gets done.
> 
> 
>  drivers/mtd/devices/m25p80.c |  160 ++++++++++++++++++++++++++++++++++++++++--
>  1 files changed, 155 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 5897889..ba4dd8b 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c

[...]

> @@ -76,6 +79,10 @@
>  #define	SR_BP2			0x10	/* Block protect 2 */
>  #define	SR_SRWD			0x80	/* SR write protect */
>  
> +/* Configuration Register bits. */
> +#define CR_QUAD_EN_SPAN		0x2     /* Spansion Quad I/O */
> +#define SR_QUAD_EN_MX		0x40    /* Macronix Quad I/O */

Two little bits of style here:
 - The other bitfields have a tab after #define (although this comes out
   to 1 character-width of whitespace, so it looks like a space)
 - We already have a listing for several Status Register (SR_*)
   bitfields; I think it makes some sense to group the SR_QUAD_EN_MX
   with the other SR_* bits and keep the CR_* macro separate. That could
   help with keeping the difference between CR and SR clearer.

> +
>  /* Define max times to check status register before we give up. */
>  #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
>  #define	MAX_CMD_SIZE		6
> @@ -95,6 +102,7 @@ struct m25p {
>  	u8			program_opcode;
>  	u8			*command;
>  	bool			fast_read;
> +	bool                    quad_read;

Did you have a response to my earlier suggestion that the fast_read and
quad_read fields be combined to a single field? This could easily be an
enum, and I think it could help some of the other code. It also wouldn't
require us to remember that quad_read takes precedence over fast_read
(which you do implicitly in this patch). And we can already foresee
additional switches needed if we add the DDR command types (Huang was
looking at this?), so we should just get it right now.

You could, perhaps, make this two patches: one for converting the bool
to an enum, and the other for supporting quad-read.

Or if you're having trouble, I could cook the first patch up.

>  };
>  
>  static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)

[...]

> @@ -1077,6 +1221,12 @@ static int m25p_probe(struct spi_device *spi)
>  		flash->addr_width = 4;
>  		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
>  			/* Dedicated 4-byte command set */
> +			if (flash->quad_read)
> +				flash->read_opcode = OPCODE_QUAD_READ_4B;
> +			else
> +				flash->read_opcode = flash->fast_read ?
> +					OPCODE_FAST_READ_4B :
> +					OPCODE_NORM_READ_4B;

Besides the repetition below (already mentioned by Huang), the above
assignment is kind of ugly again, mixing ?: and if/else. If we're
keeping the fast_read/quad_read bools, it should be:

	if (flash->quad_read)
		flash->read_opcode = OPCODE_QUAD_READ_4B;
	else if (flash->fast_read)
		flash->read_opcode = OPCODE_FAST_READ_4B;
	else
		flash->read_opcode = OPCODE_NORM_READ_4B;

(or if we use an enum, it's just a switch statement...)

>  			flash->read_opcode = flash->fast_read ?
>  				OPCODE_FAST_READ_4B :
>  				OPCODE_NORM_READ_4B;

Brian


From ezequiel.garcia at free-electrons.com  Wed Oct 30 19:19:57 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Wed, 30 Oct 2013 20:19:57 -0300
Subject: [PATCH 0/1] Fix OMAP2 NAND ONFI device detection
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA2D41D@DBDE04.ent.ti.com>
References: <1383126788-27426-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131030191414.GA16668@norris.computersforpeace.net>
 <20980858CB6D3A4BAE95CA194937D5E73EA2D41D@DBDE04.ent.ti.com>
Message-ID: <20131030231956.GA2489@localhost>

Pekon,

Let me answer this one alone, given it's an important question.

On Wed, Oct 30, 2013 at 09:18:53PM +0000, Gupta, Pekon wrote:
> > 
> > I'm not sure, of course, but I don't see why not. It's more likely to
> > break for x16 than it is for x8.
> > 
> Another question here is ..
> The above patch assumes that user has configured GPMC bus-width
> correctly, so if user is already providing GPMC bus-width information
> via DT, then do we really need to detect NAND device bus-width again
> using NAND_BUSWIDTH_AUTO ?
>

Hm.. I think you're forgetting the original motivation for this patch,
which was initially explained by you :-) The problem is ONFI doesn't work
in 16-bit mode.

Let me clarify. Since GPMC and NAND widths *must* match (otherwise, it
wouldn't make much sense, right?) we don't really need to autodetect the
NAND width.

However, since ONFI doesn't work in 16-bit mode, we would have to do
something like this (untested pseudo code):

  nand_scan_ident(...);

  if (platform_data->devsize == 16)
  	nand_chip->options |= NAND_BUSWIDTH_16;

And in some cases we might even get away with such solution. However,
we can't guarantee nand_scan_ident() doesn't need to swith to 16-bit mode
inside to perform other commands (maybe some ONFI extended parameter page).

Therefore, and given the width can be autodetected in any case (array
or ONFI based carry such information) it's much cleaner to simply do:

  nand_chip->options |= NAND_BUSWIDTH_AUTOMAGIC;
  nand_scan_ident(...);

See? Much cleaner, no?

And remember: the fact that we must know the device width to configure
the GPMC correctly (which being a hardware parameter belongs to the DT)
is OMAP specific. Other SoCs might not have such memory controller
and thus won't need such knowledge before hand, although that sounds
unlikely to me.

The outcome of this discussion seems to be that no driver should ever
need to specify the 'nand-bus-width' DT property, as Brian
previously suggested, right?

I must admit I'm a bit puzzled by seeing most drivers setting 16-bit
before calling nand_scan_ident(). I guess none of them relies on ONFI?
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Wed Oct 30 19:38:09 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 19:38:09 -0400
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <201310271732.42518.marex@denx.de>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <1382583503-13748-4-git-send-email-computersforpeace@gmail.com>
 <201310271732.42518.marex@denx.de>
Message-ID: <20131030233809.GE20059@norris.computersforpeace.net>

I see I never responded to this one.

On Sun, Oct 27, 2013 at 05:32:42PM +0100, Marek Vasut wrote:
> Hi Brian,
> 
> > Remove the compile-time option for FAST_READ, since we have run-time
> > support for detecting it.
> > 
> > Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> > ---
> >  drivers/mtd/devices/Kconfig  |  7 -------
> >  drivers/mtd/devices/m25p80.c | 11 ++++++-----
> >  2 files changed, 6 insertions(+), 12 deletions(-)
> > 
> > diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> > index 74ab4b7..0128138 100644
> > --- a/drivers/mtd/devices/Kconfig
> > +++ b/drivers/mtd/devices/Kconfig
> > @@ -95,13 +95,6 @@ config MTD_M25P80
> >  	  if you want to specify device partitioning or to use a device which
> >  	  doesn't support the JEDEC ID instruction.
> > 
> > -config M25PXX_USE_FAST_READ
> > -	bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz"
> > -	depends on MTD_M25P80
> > -	default y
> > -	help
> > -	  This option enables FAST_READ access supported by ST M25Pxx.
> > -
> >  config MTD_SPEAR_SMI
> >  	tristate "SPEAR MTD NOR Support through SMI controller"
> >  	depends on PLAT_SPEAR
> > diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> > index 7e3ec7a..d6c5c57 100644
> > --- a/drivers/mtd/devices/m25p80.c
> > +++ b/drivers/mtd/devices/m25p80.c
> > @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
> >  	flash->page_size = info->page_size;
> >  	flash->mtd.writebufsize = flash->page_size;
> > 
> > -	flash->fast_read = false;
> > -	if (np && of_property_read_bool(np, "m25p,fast-read"))
> > +	if (np)
> > +		/* If we were instantiated by DT, use it */
> > +		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
> > +	else
> > +		/* If we weren't instantiated by DT, default to fast-read */
> >  		flash->fast_read = true;
> 
> We should default to FALSE , unless explicitly requested by DT, am I wrong? 
> Otherwise this might break the old chips.

I believe my patch is simply a refactoring of the existing code with the
assumption that M25PXX_USE_FAST_READ=y. (In my experience, everyone has
it set to y. Perhaps I'm wrong.)

Now, it's unclear to me what this Kconfig was used for. It's the wrong
approach for controlling fast read on a per-controller or
per-flash-device basis, as it provides a blunt hammer to disable it for
ALL systems which might use the same kernel (think multiplatform
kernels). And now we have a better alternative: the M25P_NO_FR flag for
flash which do not support fast-read.

However, if we come across SPI controllers which can't handle this, then
we might have a problem. Such a situation would really suggest that we
need to identify whether a SPI controller supports fast-read, not just
the flash device.

(Side note: IMO, given the fact that we have to have an ID table for
these flash anyway, the DT property simply provides redundant
information. In the case of the quad-read patch, we were able to
identify this early to avoid an unnecessary DT binding. But in this
case, we also have an indication of controller support for quad I/O...)

If you still object to this patch, I can drop the patch from l2-mtd.git
for now. Then Sourav will need to rebase his patch again.

Brian


From computersforpeace at gmail.com  Wed Oct 30 19:42:51 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 19:42:51 -0400
Subject: [PATCH] mtd: m25p80: fixup device removal failure path
Message-ID: <1383176571-28057-1-git-send-email-computersforpeace@gmail.com>

Device removal shouls fail if MTD unregistration fails.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 drivers/mtd/devices/m25p80.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 58978892c321..7eda71dbc183 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -1125,9 +1125,7 @@ static int m25p_remove(struct spi_device *spi)
 	struct m25p	*flash = spi_get_drvdata(spi);
 
 	/* Clean up MTD stuff. */
-	mtd_device_unregister(&flash->mtd);
-
-	return 0;
+	return mtd_device_unregister(&flash->mtd);
 }
 
 
-- 
1.8.1.2



From computersforpeace at gmail.com  Wed Oct 30 22:29:35 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Wed, 30 Oct 2013 22:29:35 -0400
Subject: [PATCH] mtd: nand_bbt: kill NAND_BBT_SCANALLPAGES
Message-ID: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>

Now that the last user of NAND_BBT_SCANALLPAGES has been removed, let's
kill this peculiar BBT feature flag.

Signed-off-by: Brian Norris <computersforpeace at gmail.com>
---
 Documentation/DocBook/mtdnand.tmpl |  2 --
 drivers/mtd/nand/nand_bbt.c        | 37 +++----------------------------------
 include/linux/mtd/bbm.h            |  2 --
 3 files changed, 3 insertions(+), 38 deletions(-)

diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index a248f42a121e..cd11926e07c7 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -1222,8 +1222,6 @@ in this page</entry>
 #define NAND_BBT_VERSION	0x00000100
 /* Create a bbt if none axists */
 #define NAND_BBT_CREATE		0x00000200
-/* Search good / bad pattern through all pages of a block */
-#define NAND_BBT_SCANALLPAGES	0x00000400
 /* Write bbt if neccecary */
 #define NAND_BBT_WRITE		0x00001000
 /* Read and write back block contents when writing bbt */
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index c75b6a7c6ea4..c0615d1526f9 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -412,25 +412,6 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
 	}
 }
 
-/* Scan a given block full */
-static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-			   loff_t offs, uint8_t *buf, size_t readlen,
-			   int scanlen, int numpages)
-{
-	int ret, j;
-
-	ret = scan_read_oob(mtd, buf, offs, readlen);
-	/* Ignore ECC errors when checking for BBM */
-	if (ret && !mtd_is_bitflip_or_eccerr(ret))
-		return ret;
-
-	for (j = 0; j < numpages; j++, buf += scanlen) {
-		if (check_pattern(buf, scanlen, mtd->writesize, bd))
-			return 1;
-	}
-	return 0;
-}
-
 /* Scan a given block partially */
 static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 			   loff_t offs, uint8_t *buf, int numpages)
@@ -477,24 +458,17 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 	struct nand_bbt_descr *bd, int chip)
 {
 	struct nand_chip *this = mtd->priv;
-	int i, numblocks, numpages, scanlen;
+	int i, numblocks, numpages;
 	int startblock;
 	loff_t from;
-	size_t readlen;
 
 	pr_info("Scanning device for bad blocks\n");
 
-	if (bd->options & NAND_BBT_SCANALLPAGES)
-		numpages = 1 << (this->bbt_erase_shift - this->page_shift);
-	else if (bd->options & NAND_BBT_SCAN2NDPAGE)
+	if (bd->options & NAND_BBT_SCAN2NDPAGE)
 		numpages = 2;
 	else
 		numpages = 1;
 
-	/* We need only read few bytes from the OOB area */
-	scanlen = 0;
-	readlen = bd->len;
-
 	if (chip == -1) {
 		numblocks = mtd->size >> this->bbt_erase_shift;
 		startblock = 0;
@@ -519,12 +493,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
 
 		BUG_ON(bd->options & NAND_BBT_NO_OOB);
 
-		if (bd->options & NAND_BBT_SCANALLPAGES)
-			ret = scan_block_full(mtd, bd, from, buf, readlen,
-					      scanlen, numpages);
-		else
-			ret = scan_block_fast(mtd, bd, from, buf, numpages);
-
+		ret = scan_block_fast(mtd, bd, from, buf, numpages);
 		if (ret < 0)
 			return ret;
 
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 95fc482cef36..36bb6a503f19 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -91,8 +91,6 @@ struct nand_bbt_descr {
  * with NAND_BBT_CREATE.
  */
 #define NAND_BBT_CREATE_EMPTY	0x00000400
-/* Search good / bad pattern through all pages of a block */
-#define NAND_BBT_SCANALLPAGES	0x00000800
 /* Write bbt if neccecary */
 #define NAND_BBT_WRITE		0x00002000
 /* Read and write back block contents when writing bbt */
-- 
1.8.1.2



From qiwang at micron.com  Thu Oct 31 00:07:10 2013
From: qiwang at micron.com (=?utf-8?B?UWkgV2FuZyDnjovotbcgKHFpd2FuZyk=?=)
Date: Thu, 31 Oct 2013 04:07:10 +0000
Subject: [PATCH 1/1]  MTD: UBI:  try to avoid program data to NOR flash
 after erasure interrupted
In-Reply-To: <1383059901.29619.52.camel@sauron.fi.intel.com>
References: <71CF8D7F32C5C24C9CD1D0E02D52498A77082AC5@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A77082DDB@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED11@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED44@NTXXIAMBX02.xacn.micron.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770AED67@NTXXIAMBX02.xacn.micron.com>
 <1382779164.5901.1.camel@karhu.quadriga.com>
 <71CF8D7F32C5C24C9CD1D0E02D52498A770B1B97@NTXXIAMBX02.xacn.micron.com>
 <1383059901.29619.52.camel@sauron.fi.intel.com>
Message-ID: <71CF8D7F32C5C24C9CD1D0E02D52498A770B220C@NTXXIAMBX02.xacn.micron.com>

On Tue, 2013-10-29 at 11:19 +0000, Artem Bityutskiy wrote:
> On Mon, 2013-10-28 at 04:54 +0000, Qi Wang ?? (qiwang) wrote:
> > On Sa, 2013-10-26 at 05:19 +0000, Artem Bityutskiy wrote:
> > > On Thu, 2013-10-10 at 08:28 +0000, Qi Wang ?? (qiwang) wrote:
> > > > But I want to say the potential risk is if low level driver program data to 
> > > > this block, it will get ?timeout error?. And the timeout period could be very 
> > > > long(almost several minutes), during this period, any operation on NOR flash 
> > > > cannot be accept. so program data to a erasure interrupted block isn?t a 
> > > > sensible action. in order to avoid program a erasure interrupted block, 
> > > > I suggest UBIFS can read this block before program data. the code changing as below:
> > > 
> > > Yes, reading first sounds like a good idea. Would you please send a
> > > patch implementing it?
> > 
> > From: Qi Wang <qiwang at micron.com>
> > 
> > nor_erase_prepare() will be called before erase a NOR flash, it will program '0'
> > into a block to mark this block. But program data into a erasure interrupted block
> > can cause program timtout(several minutes at most) error, could impact other 
> > operation on NOR flash. So UBIFS can read this block first to avoid unneeded 
> > program operation. 
> > 
> > This patch try to put read operation at at head of write operation in 
> > nor_erase_prepare(), read out the data. 
> > If the data is already corrupt, then no need to program any data into this block, 
> > just go to erase this block.
> > 
> > Signed-off-by: Qi Wang <qiwang at qiwang@micron.com>
> > ---
> > diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
> > index bf79def..be6ab56 100644
> > --- a/drivers/mtd/ubi/io.c
> > +++ b/drivers/mtd/ubi/io.c
> > @@ -509,26 +509,10 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
> >  	struct ubi_vid_hdr vid_hdr;
> >  
> >  	/*
> > -	 * It is important to first invalidate the EC header, and then the VID
> > -	 * header. Otherwise a power cut may lead to valid EC header and
> > -	 * invalid VID header, in which case UBI will treat this PEB as
> > -	 * corrupted and will try to preserve it, and print scary warnings.
> > -	 */
> > -	addr = (loff_t)pnum * ubi->peb_size;
> > -	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
> > -	if (!err) {
> > -		addr += ubi->vid_hdr_aloffset;
> > -		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
> > -		if (!err)
> > -			return 0;
> > -	}
> 
> How about structuring the code this way:
> 
> if (EC header is good)
>      invalidate EC header()
> if (VID header is good)
>      invalidate VID header()
> 
> Then you'll handle the case when only one of the headers is already
> corrupted.
>
> -- 
> Best Regards,
> Artem Bityutskiy


Hi Artem:
Please check below patch. 

From: Qi Wang <qiwang at micron.com>

nor_erase_prepare() will be called before erase a NOR flash, it will program '0'
into a block to mark this block. But program data into a erasure interrupted block
can cause program timtout(several minutes at most) error, could impact other 
operation on NOR flash. So UBIFS can read this block first to avoid unneeded 
program operation. 
 
This patch try to put read operation at at head of write operation in 
nor_erase_prepare(), read out the data. 
If the data is already corrupt, then no need to program any data into this block, 
just go to erase this block.

Signed-off-by: Qi Wang <qiwang at qiwang@micron.com>
---
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index bf79def..0fdaca9 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -499,59 +499,44 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum)
 	size_t written;
 	loff_t addr;
 	uint32_t data = 0;
-	/*
-	 * Note, we cannot generally define VID header buffers on stack,
-	 * because of the way we deal with these buffers (see the header
-	 * comment in this file). But we know this is a NOR-specific piece of
-	 * code, so we can do this. But yes, this is error-prone and we should
-	 * (pre-)allocate VID header buffer instead.
-	 */
 	struct ubi_vid_hdr vid_hdr;
+	struct ubi_ec_hdr ec_hdr;
+
+	addr = (loff_t)pnum * ubi->peb_size;
 
 	/*
+	 * If VID or EC is valid, need to corrupt it before erase operation.  
 	 * It is important to first invalidate the EC header, and then the VID
 	 * header. Otherwise a power cut may lead to valid EC header and
 	 * invalid VID header, in which case UBI will treat this PEB as
 	 * corrupted and will try to preserve it, and print scary warnings.
 	 */
-	addr = (loff_t)pnum * ubi->peb_size;
-	err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
-	if (!err) {
-		addr += ubi->vid_hdr_aloffset;
-		err = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
-		if (!err)
-			return 0;
+	err = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
+	if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
+	    err != UBI_IO_FF){
+		err1 = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+		if(err1)
+			goto error;
 	}
 
-	/*
-	 * We failed to write to the media. This was observed with Spansion
-	 * S29GL512N NOR flash. Most probably the previously eraseblock erasure
-	 * was interrupted at a very inappropriate moment, so it became
-	 * unwritable. In this case we probably anyway have garbage in this
-	 * PEB.
-	 */
-	err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
-	if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
-	    err1 == UBI_IO_FF) {
-		struct ubi_ec_hdr ec_hdr;
-
-		err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0);
-		if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR ||
-		    err1 == UBI_IO_FF)
-			/*
-			 * Both VID and EC headers are corrupted, so we can
-			 * safely erase this PEB and not afraid that it will be
-			 * treated as a valid PEB in case of an unclean reboot.
-			 */
-			return 0;
+	err = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0);
+	if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR &&
+	    err != UBI_IO_FF){
+	    	addr += ubi->vid_hdr_aloffset;
+		err1 = mtd_write(ubi->mtd, addr, 4, &written, (void *)&data);
+		if (err1)
+			goto error;	
 	}
 
+	return 0;
+	
+error:
 	/*
-	 * The PEB contains a valid VID header, but we cannot invalidate it.
+	 * The PEB contains a valid VID or EC header, but we cannot invalidate it.
 	 * Supposedly the flash media or the driver is screwed up, so return an
 	 * error.
 	 */
-	ubi_err("cannot invalidate PEB %d, write returned %d read returned %d",
+	ubi_err("cannot invalidate PEB %d, read returned %d write returned %d ",
 		pnum, err, err1);
 	ubi_dump_flash(ubi, pnum, 0, ubi->peb_size);
 	return -EIO;
---

My Comments for above changing:
1. 
	-	/*
	-	 * Note, we cannot generally define VID header buffers on stack,
	-	 * because of the way we deal with these buffers (see the header
	-	 * comment in this file). But we know this is a NOR-specific piece of
	-	 * code, so we can do this. But yes, this is error-prone and we should
	-	 * (pre-)allocate VID header buffer instead.
	-	 */
	I remove above comment, because I pre-allocate VID header and EC header together. 
	So I think no need to emphasize VID header buffers cannot be on stack.
	(Maybe my understanding about this comment is error, if so, please correct me)

2.
	why use
	"if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR && err != UBI_IO_FF)"
	but not 
	"if (!err)" 
	to judge if need to program '0' to invalid this block.

	In case err == UBI_IO_FF_BITFLIPS, err == UBI_IO_BITFLIPS or unexpected value return
	from read function, I think UBI still need to invalid this block for above mentioned 
	condition. So I use
	"if (err != UBI_IO_BAD_HDR_EBADMSG && err != UBI_IO_BAD_HDR && err != UBI_IO_FF)"
	to judge.  


Please make me known if my understanding isn't right. 
Thanks




From sourav.poddar at ti.com  Thu Oct 31 01:01:23 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 31 Oct 2013 10:31:23 +0530
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <20131030231930.GD20059@norris.computersforpeace.net>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
 <20131030231930.GD20059@norris.computersforpeace.net>
Message-ID: <5271E423.9030506@ti.com>

On Thursday 31 October 2013 04:49 AM, Brian Norris wrote:
> On Wed, Oct 30, 2013 at 02:50:02PM +0530, Sourav Poddar wrote:
>> Some flash also support quad read mode.
>> Adding support for adding quad mode in m25p80
>> for spansion and macronix flash.
>>
>> Signed-off-by: Sourav Poddar<sourav.poddar at ti.com>
>> ---
>> Rebase this on latest l2mtd.
>> v1->v2:
>> Small dev_err message fix to make it
>> mode appropriate.
>> v1: http://patchwork.ozlabs.org/patch/286109/
>>
>> There is one cleanup suggestion from Marek Vasut on read_sr
>> value. I will take that up as a seperate patch, once this
>> patch gets done.
>>
>>
>>   drivers/mtd/devices/m25p80.c |  160 ++++++++++++++++++++++++++++++++++++++++--
>>   1 files changed, 155 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
>> index 5897889..ba4dd8b 100644
>> --- a/drivers/mtd/devices/m25p80.c
>> +++ b/drivers/mtd/devices/m25p80.c
> [...]
>
>> @@ -76,6 +79,10 @@
>>   #define	SR_BP2			0x10	/* Block protect 2 */
>>   #define	SR_SRWD			0x80	/* SR write protect */
>>
>> +/* Configuration Register bits. */
>> +#define CR_QUAD_EN_SPAN		0x2     /* Spansion Quad I/O */
>> +#define SR_QUAD_EN_MX		0x40    /* Macronix Quad I/O */
> Two little bits of style here:
>   - The other bitfields have a tab after #define (although this comes out
>     to 1 character-width of whitespace, so it looks like a space)
>   - We already have a listing for several Status Register (SR_*)
>     bitfields; I think it makes some sense to group the SR_QUAD_EN_MX
>     with the other SR_* bits and keep the CR_* macro separate. That could
>     help with keeping the difference between CR and SR clearer.
>
Ok. Will change.
>> +
>>   /* Define max times to check status register before we give up. */
>>   #define	MAX_READY_WAIT_JIFFIES	(40 * HZ)	/* M25P16 specs 40s max chip erase */
>>   #define	MAX_CMD_SIZE		6
>> @@ -95,6 +102,7 @@ struct m25p {
>>   	u8			program_opcode;
>>   	u8			*command;
>>   	bool			fast_read;
>> +	bool                    quad_read;
> Did you have a response to my earlier suggestion that the fast_read and
> quad_read fields be combined to a single field? This could easily be an
> enum, and I think it could help some of the other code. It also wouldn't
> require us to remember that quad_read takes precedence over fast_read
> (which you do implicitly in this patch). And we can already foresee
> additional switches needed if we add the DDR command types (Huang was
> looking at this?), so we should just get it right now.
>
> You could, perhaps, make this two patches: one for converting the bool
> to an enum, and the other for supporting quad-read.
>
I read that, and I was planning to take that as a seperate excercise, 
but yes I
will cook this into two independent patches.
> Or if you're having trouble, I could cook the first patch up.
>
>>   };
>>
>>   static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
> [...]
>
>> @@ -1077,6 +1221,12 @@ static int m25p_probe(struct spi_device *spi)
>>   		flash->addr_width = 4;
>>   		if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) {
>>   			/* Dedicated 4-byte command set */
>> +			if (flash->quad_read)
>> +				flash->read_opcode = OPCODE_QUAD_READ_4B;
>> +			else
>> +				flash->read_opcode = flash->fast_read ?
>> +					OPCODE_FAST_READ_4B :
>> +					OPCODE_NORM_READ_4B;
> Besides the repetition below (already mentioned by Huang), the above
> assignment is kind of ugly again, mixing ?: and if/else. If we're
> keeping the fast_read/quad_read bools, it should be:
>
> 	if (flash->quad_read)
> 		flash->read_opcode = OPCODE_QUAD_READ_4B;
> 	else if (flash->fast_read)
> 		flash->read_opcode = OPCODE_FAST_READ_4B;
> 	else
> 		flash->read_opcode = OPCODE_NORM_READ_4B;
>
> (or if we use an enum, it's just a switch statement...)
>
Ok.
>>   			flash->read_opcode = flash->fast_read ?
>>   				OPCODE_FAST_READ_4B :
>>   				OPCODE_NORM_READ_4B;
> Brian



From horms at verge.net.au  Thu Oct 31 01:52:28 2013
From: horms at verge.net.au (Simon Horman)
Date: Thu, 31 Oct 2013 14:52:28 +0900
Subject: [PATCH v2 00/19] Enable various Renesas drivers on all ARM
 platforms
In-Reply-To: <1383086274-11049-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
References: <1383086274-11049-1-git-send-email-laurent.pinchart+renesas@ideasonboard.com>
Message-ID: <20131031055228.GS1603@verge.net.au>

On Tue, Oct 29, 2013 at 11:37:35PM +0100, Laurent Pinchart wrote:
> Hello,
> 
> This patch series, based on v3.12-rc7, prepares various Renesas drivers
> for migration to multiplatform kernels by enabling their compilation or
> otherwise fixing them on all ARM platforms. The patches are pretty
> straightforward and are described in their commit message.
> 
> Changes since v1:
> 
> - The drivers can also be selected when COMPILE_TEST is enabled, regardless of
>   the architecture. This should provide a good compromise between wide build
>   test coverage and not clobbering configuration with drivers useless on
>   non-SuperH, non-ARM platforms.
> 
> - DMA configuration is now unconditional in patch 08/19
> 
> I'd like to get all these patches merged in v3.14. As they will need to go
> through their respective subsystems' trees, I would appreciate if all
> maintainers involved could notify me when they merge patches from this series
> in their tree to help me tracking the merge status. I don't plan to send pull
> requests individually for these patches, and I will repost patches
> individually if changes are requested during review.
> 
> If you believe the issue should be solved in a different way please reply to
> the cover letter to let other maintainers chime in.

All patches, including the v3 ones present in the thread at this time:

Acked-by: Simon Horman <horms at verge.net.au>

> Cc: Chris Ball <cjb at laptop.org>
> Cc: "David S. Miller" <davem at davemloft.net>
> Cc: David Woodhouse <dwmw2 at infradead.org>
> Cc: Dmitry Torokhov <dmitry.torokhov at gmail.com>
> Cc: Eduardo Valentin <eduardo.valentin at ti.com>
> Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Cc: Guennadi Liakhovetski <g.liakhovetski+renesas at gmail.com>
> Cc: Ian Molton <ian at mnementh.co.uk>
> Cc: iommu at lists.linux-foundation.org
> Cc: Jean-Christophe Plagniol-Villard <plagnioj at jcrosoft.com>
> Cc: Joerg Roedel <joro at 8bytes.org>
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Magnus Damm <magnus.damm at gmail.com>
> Cc: Mark Brown <broonie at kernel.org>
> Cc: Mauro Carvalho Chehab <m.chehab at samsung.com>
> Cc: Samuel Ortiz <samuel at sortiz.org>
> Cc: Sergei Shtylyov <sergei.shtylyov at cogentembedded.com>
> Cc: Thierry Reding <thierry.reding at gmail.com>
> Cc: Tomi Valkeinen <tomi.valkeinen at ti.com>
> Cc: Vinod Koul <vinod.koul at intel.com>
> Cc: Wolfram Sang <wsa at the-dreams.de>
> Cc: Zhang Rui <rui.zhang at intel.com>
> Cc: dmaengine at vger.kernel.org
> Cc: linux-fbdev at vger.kernel.org
> Cc: linux-i2c at vger.kernel.org
> Cc: linux-input at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-media at vger.kernel.org
> Cc: linux-mmc at vger.kernel.org
> Cc: linux-mtd at lists.infradead.org
> Cc: linux-pm at vger.kernel.org
> Cc: linux-pwm at vger.kernel.org
> Cc: linux-serial at vger.kernel.org
> Cc: linux-spi at vger.kernel.org
> Cc: netdev at vger.kernel.org
> 
> Laurent Pinchart (19):
>   serial: sh-sci: Enable the driver on all ARM platforms
>   DMA: shdma: Enable the driver on all ARM platforms
>   i2c: sh_mobile: Enable the driver on all ARM platforms
>   input: sh_keysc: Enable the driver on all ARM platforms
>   iommu: shmobile: Enable the driver on all ARM platforms
>   i2c: rcar: Enable the driver on all ARM platforms
>   v4l: sh_vou: Enable the driver on all ARM platforms
>   mmc: sdhi: Enable the driver on all ARM platforms
>   mmc: sh_mmcif: Enable the driver on all ARM platforms
>   mtd: sh_flctl: Enable the driver on all ARM platforms
>   net: sh_eth: Set receive alignment correctly on all ARM platforms
>   irda: sh_irda: Enable the driver on all ARM platforms
>   pinctrl: sh-pfc: Enable the driver on all ARM platforms
>   pwm: pwm-renesas-tpu: Enable the driver on all ARM platforms
>   sh: intc: Enable the driver on all ARM platforms
>   spi: sh_msiof: Enable the driver on all ARM platforms
>   spi: sh_hspi: Enable the driver on all ARM platforms
>   thermal: rcar-thermal: Enable the driver on all ARM platforms
>   fbdev: sh-mobile-lcdcfb: Enable the driver on all ARM platforms
> 
>  drivers/dma/sh/Kconfig                | 2 +-
>  drivers/dma/sh/shdmac.c               | 6 +++---
>  drivers/i2c/busses/Kconfig            | 4 ++--
>  drivers/input/keyboard/Kconfig        | 2 +-
>  drivers/iommu/Kconfig                 | 2 +-
>  drivers/media/platform/Kconfig        | 2 +-
>  drivers/mmc/host/Kconfig              | 4 ++--
>  drivers/mmc/host/tmio_mmc_dma.c       | 4 +---
>  drivers/mtd/nand/Kconfig              | 2 +-
>  drivers/net/ethernet/renesas/sh_eth.c | 2 +-
>  drivers/net/ethernet/renesas/sh_eth.h | 2 +-
>  drivers/net/irda/Kconfig              | 2 +-
>  drivers/pinctrl/Makefile              | 2 +-
>  drivers/pinctrl/sh-pfc/Kconfig        | 2 +-
>  drivers/pwm/Kconfig                   | 2 +-
>  drivers/sh/intc/Kconfig               | 2 +-
>  drivers/spi/Kconfig                   | 4 ++--
>  drivers/thermal/Kconfig               | 2 +-
>  drivers/tty/serial/Kconfig            | 2 +-
>  drivers/video/Kconfig                 | 6 +++---
>  20 files changed, 27 insertions(+), 29 deletions(-)
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From marex at denx.de  Thu Oct 31 03:36:36 2013
From: marex at denx.de (Marek Vasut)
Date: Thu, 31 Oct 2013 08:36:36 +0100
Subject: [PATCH] mtd: m25p80: fixup device removal failure path
In-Reply-To: <1383176571-28057-1-git-send-email-computersforpeace@gmail.com>
References: <1383176571-28057-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <201310310836.36976.marex@denx.de>

Dear Brian Norris,

> Device removal shouls fail if MTD unregistration fails.

should ;-)

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

> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> ---
>  drivers/mtd/devices/m25p80.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
> index 58978892c321..7eda71dbc183 100644
> --- a/drivers/mtd/devices/m25p80.c
> +++ b/drivers/mtd/devices/m25p80.c
> @@ -1125,9 +1125,7 @@ static int m25p_remove(struct spi_device *spi)
>  	struct m25p	*flash = spi_get_drvdata(spi);
> 
>  	/* Clean up MTD stuff. */
> -	mtd_device_unregister(&flash->mtd);
> -
> -	return 0;
> +	return mtd_device_unregister(&flash->mtd);
>  }

Best regards,
Marek Vasut


From marex at denx.de  Thu Oct 31 05:21:42 2013
From: marex at denx.de (Marek Vasut)
Date: Thu, 31 Oct 2013 10:21:42 +0100
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <20131030233809.GE20059@norris.computersforpeace.net>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <201310271732.42518.marex@denx.de>
 <20131030233809.GE20059@norris.computersforpeace.net>
Message-ID: <201310311021.42620.marex@denx.de>

Dear Brian Norris,

> I see I never responded to this one.
> 
> On Sun, Oct 27, 2013 at 05:32:42PM +0100, Marek Vasut wrote:
> > Hi Brian,
> > 
> > > Remove the compile-time option for FAST_READ, since we have run-time
> > > support for detecting it.
> > > 
> > > Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> > > ---
> > > 
> > >  drivers/mtd/devices/Kconfig  |  7 -------
> > >  drivers/mtd/devices/m25p80.c | 11 ++++++-----
> > >  2 files changed, 6 insertions(+), 12 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
> > > index 74ab4b7..0128138 100644
> > > --- a/drivers/mtd/devices/Kconfig
> > > +++ b/drivers/mtd/devices/Kconfig
> > > @@ -95,13 +95,6 @@ config MTD_M25P80
> > > 
> > >  	  if you want to specify device partitioning or to use a device which
> > >  	  doesn't support the JEDEC ID instruction.
> > > 
> > > -config M25PXX_USE_FAST_READ
> > > -	bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz"
> > > -	depends on MTD_M25P80
> > > -	default y
> > > -	help
> > > -	  This option enables FAST_READ access supported by ST M25Pxx.
> > > -
> > > 
> > >  config MTD_SPEAR_SMI
> > >  
> > >  	tristate "SPEAR MTD NOR Support through SMI controller"
> > >  	depends on PLAT_SPEAR
> > > 
> > > diff --git a/drivers/mtd/devices/m25p80.c
> > > b/drivers/mtd/devices/m25p80.c index 7e3ec7a..d6c5c57 100644
> > > --- a/drivers/mtd/devices/m25p80.c
> > > +++ b/drivers/mtd/devices/m25p80.c
> > > @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
> > > 
> > >  	flash->page_size = info->page_size;
> > >  	flash->mtd.writebufsize = flash->page_size;
> > > 
> > > -	flash->fast_read = false;
> > > -	if (np && of_property_read_bool(np, "m25p,fast-read"))
> > > +	if (np)
> > > +		/* If we were instantiated by DT, use it */
> > > +		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
> > > +	else
> > > +		/* If we weren't instantiated by DT, default to fast-read */
> > > 
> > >  		flash->fast_read = true;
> > 
> > We should default to FALSE , unless explicitly requested by DT, am I
> > wrong? Otherwise this might break the old chips.
> 
> I believe my patch is simply a refactoring of the existing code with the
> assumption that M25PXX_USE_FAST_READ=y. (In my experience, everyone has
> it set to y. Perhaps I'm wrong.)

OK, this is where we diverged. I always set FAST_READ to =n and only enabled it 
via this DT prop if I was dead sure the chip could do it.

> Now, it's unclear to me what this Kconfig was used for. It's the wrong
> approach for controlling fast read on a per-controller or
> per-flash-device basis, as it provides a blunt hammer to disable it for
> ALL systems which might use the same kernel (think multiplatform
> kernels). And now we have a better alternative: the M25P_NO_FR flag for
> flash which do not support fast-read.

This Kconfig was entirely wrong. I suspect it was there from the old times to 
force-enable the fast read and was meant for simple systems with one SPI NOR. 
Multiplatform kernels weren't taken into consideration here, the thing was added 
5 years ago.

commit 2230b76b3838a37167f80487c694d8691248da9f
Date:   Fri Apr 25 12:07:32 2008 +0800

    [MTD] m25p80: add FAST_READ access support to M25Pxx

> However, if we come across SPI controllers which can't handle this, then
> we might have a problem. Such a situation would really suggest that we
> need to identify whether a SPI controller supports fast-read, not just
> the flash device.

The FAST_READ is entirely flash-device thing, it has nothing to do with the 
controller. I wonder why there's this 50 MHz limit in the kernel config at all. 
My understanding of FAST_READ is that after you send FAST_READ opcode, you can 
read all you want until CS is toggled, only then you can send another opcode. 
The "slow" READ opcode on the other hand has to be sent for each block.

> (Side note: IMO, given the fact that we have to have an ID table for
> these flash anyway, the DT property simply provides redundant
> information.

Side note: I wonder how we should handle exotic chips like the N25Q256A which 
recycle the ID for different chips with different capabilities though. We might 
need to have some DT props.

> In the case of the quad-read patch, we were able to
> identify this early to avoid an unnecessary DT binding. But in this
> case, we also have an indication of controller support for quad I/O...)

Yes. I see your point why the fast-read might be redundant.

> If you still object to this patch, I can drop the patch from l2-mtd.git
> for now. Then Sourav will need to rebase his patch again.
> 
> Brian


From sourav.poddar at ti.com  Thu Oct 31 05:50:13 2013
From: sourav.poddar at ti.com (Sourav Poddar)
Date: Thu, 31 Oct 2013 15:20:13 +0530
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <201310311021.42620.marex@denx.de>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <201310271732.42518.marex@denx.de>
 <20131030233809.GE20059@norris.computersforpeace.net>
 <201310311021.42620.marex@denx.de>
Message-ID: <527227D5.6070809@ti.com>

On Thursday 31 October 2013 02:51 PM, Marek Vasut wrote:
> Dear Brian Norris,
>
>> I see I never responded to this one.
>>
>> On Sun, Oct 27, 2013 at 05:32:42PM +0100, Marek Vasut wrote:
>>> Hi Brian,
>>>
>>>> Remove the compile-time option for FAST_READ, since we have run-time
>>>> support for detecting it.
>>>>
>>>> Signed-off-by: Brian Norris<computersforpeace at gmail.com>
>>>> ---
>>>>
>>>>   drivers/mtd/devices/Kconfig  |  7 -------
>>>>   drivers/mtd/devices/m25p80.c | 11 ++++++-----
>>>>   2 files changed, 6 insertions(+), 12 deletions(-)
>>>>
>>>> diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
>>>> index 74ab4b7..0128138 100644
>>>> --- a/drivers/mtd/devices/Kconfig
>>>> +++ b/drivers/mtd/devices/Kconfig
>>>> @@ -95,13 +95,6 @@ config MTD_M25P80
>>>>
>>>>   	  if you want to specify device partitioning or to use a device which
>>>>   	  doesn't support the JEDEC ID instruction.
>>>>
>>>> -config M25PXX_USE_FAST_READ
>>>> -	bool "Use FAST_READ OPCode allowing SPI CLK>= 50MHz"
>>>> -	depends on MTD_M25P80
>>>> -	default y
>>>> -	help
>>>> -	  This option enables FAST_READ access supported by ST M25Pxx.
>>>> -
>>>>
>>>>   config MTD_SPEAR_SMI
>>>>
>>>>   	tristate "SPEAR MTD NOR Support through SMI controller"
>>>>   	depends on PLAT_SPEAR
>>>>
>>>> diff --git a/drivers/mtd/devices/m25p80.c
>>>> b/drivers/mtd/devices/m25p80.c index 7e3ec7a..d6c5c57 100644
>>>> --- a/drivers/mtd/devices/m25p80.c
>>>> +++ b/drivers/mtd/devices/m25p80.c
>>>> @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
>>>>
>>>>   	flash->page_size = info->page_size;
>>>>   	flash->mtd.writebufsize = flash->page_size;
>>>>
>>>> -	flash->fast_read = false;
>>>> -	if (np&&  of_property_read_bool(np, "m25p,fast-read"))
>>>> +	if (np)
>>>> +		/* If we were instantiated by DT, use it */
>>>> +		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
>>>> +	else
>>>> +		/* If we weren't instantiated by DT, default to fast-read */
>>>>
>>>>   		flash->fast_read = true;
>>> We should default to FALSE , unless explicitly requested by DT, am I
>>> wrong? Otherwise this might break the old chips.
>> I believe my patch is simply a refactoring of the existing code with the
>> assumption that M25PXX_USE_FAST_READ=y. (In my experience, everyone has
>> it set to y. Perhaps I'm wrong.)
> OK, this is where we diverged. I always set FAST_READ to =n and only enabled it
> via this DT prop if I was dead sure the chip could do it.
>
>> Now, it's unclear to me what this Kconfig was used for. It's the wrong
>> approach for controlling fast read on a per-controller or
>> per-flash-device basis, as it provides a blunt hammer to disable it for
>> ALL systems which might use the same kernel (think multiplatform
>> kernels). And now we have a better alternative: the M25P_NO_FR flag for
>> flash which do not support fast-read.
> This Kconfig was entirely wrong. I suspect it was there from the old times to
> force-enable the fast read and was meant for simple systems with one SPI NOR.
> Multiplatform kernels weren't taken into consideration here, the thing was added
> 5 years ago.
>
> commit 2230b76b3838a37167f80487c694d8691248da9f
> Date:   Fri Apr 25 12:07:32 2008 +0800
>
>      [MTD] m25p80: add FAST_READ access support to M25Pxx
>
I tried to work around this in my quad patch, where based on some
check, I have tried to assign opcode to quad or fast read. By default, I 
have
kept the command to NORMAL read.
>> However, if we come across SPI controllers which can't handle this, then
>> we might have a problem. Such a situation would really suggest that we
>> need to identify whether a SPI controller supports fast-read, not just
>> the flash device.
> The FAST_READ is entirely flash-device thing, it has nothing to do with the
> controller. I wonder why there's this 50 MHz limit in the kernel config at all.
> My understanding of FAST_READ is that after you send FAST_READ opcode, you can
> read all you want until CS is toggled, only then you can send another opcode.
> The "slow" READ opcode on the other hand has to be sent for each block.
>
I dont think resending commands after each block comes into picture for
slow read. What differnece I see between NORMAL(slow) ad fast read is
just the dummy bytes.
>> (Side note: IMO, given the fact that we have to have an ID table for
>> these flash anyway, the DT property simply provides redundant
>> information.
> Side note: I wonder how we should handle exotic chips like the N25Q256A which
> recycle the ID for different chips with different capabilities though. We might
> need to have some DT props.
>
>> In the case of the quad-read patch, we were able to
>> identify this early to avoid an unnecessary DT binding. But in this
>> case, we also have an indication of controller support for quad I/O...)
> Yes. I see your point why the fast-read might be redundant.
>
>> If you still object to this patch, I can drop the patch from l2-mtd.git
>> for now. Then Sourav will need to rebase his patch again.
>>
>> Brian



From ezequiel.garcia at free-electrons.com  Thu Oct 31 06:20:39 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 31 Oct 2013 07:20:39 -0300
Subject: [PATCH] mtd: nand_bbt: kill NAND_BBT_SCANALLPAGES
In-Reply-To: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
References: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131031102038.GA2391@localhost>

On Wed, Oct 30, 2013 at 10:29:35PM -0400, Brian Norris wrote:
> Now that the last user of NAND_BBT_SCANALLPAGES has been removed, let's
> kill this peculiar BBT feature flag.
> 

I must admit I also find this option a bit puzzling.

However, I'm wondering what happens if a manufacturer specifies
the bad block mark is in some page at the middle of a block.

AFAIK, some of them do exactly that, and I've always thought
this option was the solution for such cases.

So, is this really no longer needed?

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From annulen at yandex.ru  Thu Oct 31 09:48:34 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Thu, 31 Oct 2013 17:48:34 +0400
Subject: Flashing UBIFS image to gluebi mtd
Message-ID: <72811383227314@web24j.yandex.ru>

Hi all,

I'm migrating rootfs of device from SquashFS on top of gluebi to UBIFS. However, old version of
firmware upgrade program writes UBIFS image to gluebi mtd device instead of using recommended
volume update procedure. While it works for SquashFS images, writing UBIFS image leads to
the next errors messages in random moments:

UBI error: ubi_io_read: error -77 while reading 76 bytes from PEB 769:26000, read 0 bytes
UBIFS error (pid 383): ubifs_read_node: cannot read node 2 from LEB 347:21904, error -5
UBIFS warning (pid 383): ubifs_ro_mode: switched to read-only mode, error -5

However, when device is rebooted first time after upgrade, UBIFS mounts successfully.

Do you have any idea what is going on and how to destinguish "broken" UBIFS volume from
correctly flashed via ubi volume device?

-- 
Regards,
Konstantin


From computersforpeace at gmail.com  Thu Oct 31 10:27:38 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 31 Oct 2013 10:27:38 -0400
Subject: [PATCH] mtd: m25p80: fixup device removal failure path
In-Reply-To: <201310310836.36976.marex@denx.de>
References: <1383176571-28057-1-git-send-email-computersforpeace@gmail.com>
 <201310310836.36976.marex@denx.de>
Message-ID: <CAN8TOE8cK-qhBB=B8zN=kSKjb0Wz+5upy3NsnaS9m42TBpPVjg@mail.gmail.com>

On Thu, Oct 31, 2013 at 3:36 AM, Marek Vasut <marex at denx.de> wrote:
>> Device removal shouls fail if MTD unregistration fails.
>
> should ;-)

Wow... I need to proofread myself a bit better. Thanks.

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

Fixed and pushed to l2-mtd.git.

Brian


From computersforpeace at gmail.com  Thu Oct 31 10:55:20 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 31 Oct 2013 10:55:20 -0400
Subject: [PATCH 4/5] mtd: m25p80: remove M25PXX_USE_FAST_READ Kconfig
In-Reply-To: <201310311021.42620.marex@denx.de>
References: <1382583503-13748-1-git-send-email-computersforpeace@gmail.com>
 <201310271732.42518.marex@denx.de>
 <20131030233809.GE20059@norris.computersforpeace.net>
 <201310311021.42620.marex@denx.de>
Message-ID: <20131031145520.GA4700@norris.computersforpeace.net>

Hi Marek,

On Thu, Oct 31, 2013 at 10:21:42AM +0100, Marek Vasut wrote:
> Dear Brian Norris,
> 
> > On Sun, Oct 27, 2013 at 05:32:42PM +0100, Marek Vasut wrote:
> > > Hi Brian,
> > > 
> > > > Remove the compile-time option for FAST_READ, since we have run-time
> > > > support for detecting it.
> > > > 
> > > > Signed-off-by: Brian Norris <computersforpeace at gmail.com>
> > > > ---
> > > > 
> > > >  drivers/mtd/devices/Kconfig  |  7 -------
> > > >  drivers/mtd/devices/m25p80.c | 11 ++++++-----
> > > >  2 files changed, 6 insertions(+), 12 deletions(-)
> > > > 
> > > > diff --git a/drivers/mtd/devices/m25p80.c
> > > > b/drivers/mtd/devices/m25p80.c index 7e3ec7a..d6c5c57 100644
> > > > --- a/drivers/mtd/devices/m25p80.c
> > > > +++ b/drivers/mtd/devices/m25p80.c
> > > > @@ -1055,13 +1055,14 @@ static int m25p_probe(struct spi_device *spi)
> > > > 
> > > >  	flash->page_size = info->page_size;
> > > >  	flash->mtd.writebufsize = flash->page_size;
> > > > 
> > > > -	flash->fast_read = false;
> > > > -	if (np && of_property_read_bool(np, "m25p,fast-read"))
> > > > +	if (np)
> > > > +		/* If we were instantiated by DT, use it */
> > > > +		flash->fast_read = of_property_read_bool(np, "m25p,fast-read");
> > > > +	else
> > > > +		/* If we weren't instantiated by DT, default to fast-read */
> > > > 
> > > >  		flash->fast_read = true;
> > > 
> > > We should default to FALSE , unless explicitly requested by DT, am I
> > > wrong? Otherwise this might break the old chips.
> > 
> > I believe my patch is simply a refactoring of the existing code with the
> > assumption that M25PXX_USE_FAST_READ=y.

Ah, my statement was wrong: for DT-instantiated devices, my patch
"defaulted" as if M25PXX_USE_FAST_READ=n; for devices without a DT node,
it defaulted as if M25PXX_USE_FAST_READ=y.

> > (In my experience, everyone has
> > it set to y. Perhaps I'm wrong.)
> 
> OK, this is where we diverged. I always set FAST_READ to =n and only enabled it 
> via this DT prop if I was dead sure the chip could do it.

Right, that actually makes sense, and your mode is not affected by my
patch. For DT-enabled devices, we default to the DT property.

The only mode that has less flexibility is for platform devices
(non-DT), where we only use normal read for devices that can't handle
FAST READ.

> > Now, it's unclear to me what this Kconfig was used for. It's the wrong
> > approach for controlling fast read on a per-controller or
> > per-flash-device basis, as it provides a blunt hammer to disable it for
> > ALL systems which might use the same kernel (think multiplatform
> > kernels). And now we have a better alternative: the M25P_NO_FR flag for
> > flash which do not support fast-read.
> 
> This Kconfig was entirely wrong. I suspect it was there from the old times to 
> force-enable the fast read and was meant for simple systems with one SPI NOR. 
> Multiplatform kernels weren't taken into consideration here, the thing was added 
> 5 years ago.

Sure, I agree.

> commit 2230b76b3838a37167f80487c694d8691248da9f
> Date:   Fri Apr 25 12:07:32 2008 +0800
> 
>     [MTD] m25p80: add FAST_READ access support to M25Pxx
> 
> > However, if we come across SPI controllers which can't handle this, then
> > we might have a problem. Such a situation would really suggest that we
> > need to identify whether a SPI controller supports fast-read, not just
> > the flash device.
> 
> The FAST_READ is entirely flash-device thing, it has nothing to do with the 
> controller. I wonder why there's this 50 MHz limit in the kernel config at all. 

I have a Spansion S25FL128S datasheet which says:

  "The maximum operating clock frequency for the READ command is 50
  MHz."

And:

  "The maximum operating clock frequency for FAST READ command is 133
  MHz."

But this does suggest, as you say, that the controller provides no
limitation on using FAST READ. However, the extra dummy cycles would be
a *slight* penalty for using FAST READ instead of (normal) READ when run
at a frequency under which either would suffice. But this likely isn't a
significant problem.

> My understanding of FAST_READ is that after you send FAST_READ opcode, you can 
> read all you want until CS is toggled, only then you can send another opcode. 
> The "slow" READ opcode on the other hand has to be sent for each block.

As Sourav said in his response, I don't believe this is true. AIUI, the
only differences are the dummy cycles and the maximum clock frequency.

> > (Side note: IMO, given the fact that we have to have an ID table for
> > these flash anyway, the DT property simply provides redundant
> > information.
> 
> Side note: I wonder how we should handle exotic chips like the N25Q256A which 
> recycle the ID for different chips with different capabilities though. We might 
> need to have some DT props.

Cross that bridge when/if we come to it, I guess? :) Do you know of any
current problems with this device?

> > In the case of the quad-read patch, we were able to
> > identify this early to avoid an unnecessary DT binding. But in this
> > case, we also have an indication of controller support for quad I/O...)
> 
> Yes. I see your point why the fast-read might be redundant.
> 
> > If you still object to this patch, I can drop the patch from l2-mtd.git
> > for now. Then Sourav will need to rebase his patch again.

So what do you think? I feel like my current patch is the right way to
go, but I think I could update the description to be more verbose, since
there are obviously a few other issues coming into play here.

Brian


From ezequiel.garcia at free-electrons.com  Thu Oct 31 11:08:45 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 31 Oct 2013 12:08:45 -0300
Subject: Flashing UBIFS image to gluebi mtd
In-Reply-To: <72811383227314@web24j.yandex.ru>
References: <72811383227314@web24j.yandex.ru>
Message-ID: <20131031150844.GA1092@localhost>

Hi Konstantin,

On Thu, Oct 31, 2013 at 05:48:34PM +0400, Konstantin Tokarev wrote:
> 
> I'm migrating rootfs of device from SquashFS on top of gluebi to UBIFS.

Sounds like you could use ubiblock for that setup, which is suitable
for squashfs, and completely independent of ubifs (thus less cpu and
memory hungry and easier to setup).

You can find some patches floating around, but the *latest* work
is here:

http://git.free-electrons.com/users/ezequiel-garcia/linux/log/?h=ubiblock-v4-cache-optional

And you'll need a patch for mtd-utils as well:

http://git.free-electrons.com/users/ezequiel-garcia/mtd-utils

Feel free to use it and report any issues. However, be very
careful as the driver is a bit experimental yet.

Others are already using it, so it should be more or less
fine!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Thu Oct 31 11:22:45 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 31 Oct 2013 11:22:45 -0400
Subject: [PATCH] mtd: nand_bbt: kill NAND_BBT_SCANALLPAGES
In-Reply-To: <20131031102038.GA2391@localhost>
References: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
 <20131031102038.GA2391@localhost>
Message-ID: <20131031152245.GB4700@norris.computersforpeace.net>

On Thu, Oct 31, 2013 at 07:20:39AM -0300, Ezequiel Garcia wrote:
> On Wed, Oct 30, 2013 at 10:29:35PM -0400, Brian Norris wrote:
> > Now that the last user of NAND_BBT_SCANALLPAGES has been removed, let's
> > kill this peculiar BBT feature flag.
> > 
> 
> I must admit I also find this option a bit puzzling.
> 
> However, I'm wondering what happens if a manufacturer specifies
> the bad block mark is in some page at the middle of a block.
> 
> AFAIK, some of them do exactly that, and I've always thought
> this option was the solution for such cases.

Well, it's not really a *good* solution for a marker in the middle of
the page, as it's both inaccurate and heavily inefficient. But honestly,
I've never heard of such a device. (There is a rare one or two that uses
the 2nd-to-last or 3rd-to-last page.) Do you have any examples?

> So, is this really no longer needed?

I think it just adds unnecessary complexity to nand_bbt.c. Generally,
the fewer (unused) options the better. Also, this helps clear the way
for some nand_base/nand_bbt simplification that I have planned.

Additionally, I think its only users were either accidental (in the case
of omap2.c) or lazy (which didn't want to figure out the correct pages
to scan for bad block markers). And now there are no users.

Brian


From ezequiel.garcia at free-electrons.com  Thu Oct 31 11:32:43 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 31 Oct 2013 12:32:43 -0300
Subject: [PATCH] mtd: nand_bbt: kill NAND_BBT_SCANALLPAGES
In-Reply-To: <20131031152245.GB4700@norris.computersforpeace.net>
References: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
 <20131031102038.GA2391@localhost>
 <20131031152245.GB4700@norris.computersforpeace.net>
Message-ID: <20131031153242.GB1092@localhost>

On Thu, Oct 31, 2013 at 11:22:45AM -0400, Brian Norris wrote:
> On Thu, Oct 31, 2013 at 07:20:39AM -0300, Ezequiel Garcia wrote:
> > On Wed, Oct 30, 2013 at 10:29:35PM -0400, Brian Norris wrote:
> > > Now that the last user of NAND_BBT_SCANALLPAGES has been removed, let's
> > > kill this peculiar BBT feature flag.
> > > 
> > 
> > I must admit I also find this option a bit puzzling.
> > 
> > However, I'm wondering what happens if a manufacturer specifies
> > the bad block mark is in some page at the middle of a block.
> > 
> > AFAIK, some of them do exactly that, and I've always thought
> > this option was the solution for such cases.
> 
> Well, it's not really a *good* solution for a marker in the middle of
> the page, as it's both inaccurate and heavily inefficient.

Granted.

> I've never heard of such a device. (There is a rare one or two that uses
> the 2nd-to-last or 3rd-to-last page.) Do you have any examples?
> 

Not at hand.

> > So, is this really no longer needed?
> 
> I think it just adds unnecessary complexity to nand_bbt.c. Generally,
> the fewer (unused) options the better. Also, this helps clear the way
> for some nand_base/nand_bbt simplification that I have planned.
> 
> Additionally, I think its only users were either accidental (in the case
> of omap2.c) or lazy (which didn't want to figure out the correct pages
> to scan for bad block markers). And now there are no users.
> 

Ok, agreed. But do we have any mechanism to scan a *particular*
page?

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Thu Oct 31 11:58:09 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 31 Oct 2013 12:58:09 -0300
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
Message-ID: <20131031155808.GB2468@localhost>

Brian,

Can we start discussing this patchset?
I realize is a big series, but better starting sooner than later! :)

In particular... (see below)

On Fri, Oct 18, 2013 at 08:02:27PM -0300, Ezequiel Garcia wrote:
> Hi guys,
> 
> This is the v2 of the work implementing NAND support in Armada 370/XP SoCs.
> This series is probably not yet complete (see below), but I feel like
> we're really closer now :-)
> 
> As in the previous version and given I don't have any public datasheet
> to show, I'll try to write some of the most relevant parts of the controller.
> 
> * NFCv2 controller background
> 
> The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
> larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
> chunked transfers.
> 
> For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
> we'll have this layout in the pages:
> 
>   ------------------------------------------------------------------------------
>   | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
>   ------------------------------------------------------------------------------
> 
> The driver reads the data and spare portions independently and builds an internal
> buffer with this layout (in the 4 KiB page case):
> 
>   ------------------------------------------
>   |     4096B data     |     64B spare     |
>   ------------------------------------------
> 
> Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
> OOB, one per chunk read.
> 
>   -------------------------------------------------------------------
>   |     4096B data     |  32B spare | 30B ECC | 32B spare | 30B ECC |
>   -------------------------------------------------------------------
> 
> So, in order to achieve reading (for instance), we issue several READ0 commands
> (with some additional controller-specific magic) and read two chunks of 2080B
> (2048 data + 32 spare) each.
> The driver accomodates this data to expose the NAND core a contiguous buffer
> (4096 data + spare) or (4096 + spare + ECC + spare + ECC).
> 
> * ECC
> 
> The controller has built-in hardware ECC capabilities. In addition it is
> configurable between two modes: 1) Hamming, 2) BCH.
> 
> Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
> the controller is configured to transfer the data.
> 
> In the BCH mode the ECC code will be calculated for each transfered chunk
> and expected to be located (when reading/programming) right after the spare
> bytes as the figure above shows.
> 
> So, repeating the above scheme, a 2048B data chunk will be followed by 32B
> spare, and then the ECC controller will read/write the ECC code (30B in
> this case):
> 
>   ------------------------------------
>   | 2048B data | 32B spare | 30B ECC |
>   ------------------------------------
> 
> If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
> If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
> So in Hamming mode, a 2048B page will have a 24B ECC.
> 
> Despite all of the above, the controller requires the driver to only read or
> write in multiples of 8-bytes, because the data buffer is 64-bits.
> 
> * Changes from v1
> 
> Aside from several changes based in Brian's feedback, the main changes
> from v1 are:
> 
>   * The controller's clock source is now fully modeled, see patche 1 to 4.
>     Of course, none of those patches should be taken through the mtd
>     subsystem, but I'm adding them here for completeness.
> 
>   * The chip's cmdfunc() is now independently implemented in each SoC variant.
>     The rationale behind this decision is that 'chunked' I/O is the only tested
>     mode on the Armada370 variant, while the old 'vanilla' I/O is the only
>     tested mode on the PXA variant.
> 
>     So it's safer to have an implementation for each variant.
> 
>   * Added support for BCH-8, in other words: 8-bits of correction in a 512-byte
>     region. This is obtained by using a data chunk size of 1024B, thus doubling
>     the ECC BCH strength, as per this ECC engine mechanism.
> 
>   * The ECC layout in use, which must be set according to the page size and
>     desired ECC strength is now strictly chosen to match only the tested
>     combinations.
> 
> * Pending stuff
> 
>   1. Factory bad blocks handling
> 
>   Currently, there's no factory bad block initial scan (when the bad block
>   table is missing). The ECC BCH requires to layout the device's pages in
>   a splitted "data + OOB + data + OOB" way. This layout being different from
>   the factory layout. In other words,
> 
>   Factory view:
> 
>   -----------------------------------------------
>   |                    Data           |x  OOB   |
>   -----------------------------------------------
> 
>   Driver's view:
> 
>   -----------------------------------------------
>   |      Data      | OOB |      Data   x  | OOB |
>   -----------------------------------------------
> 
>   It can be seen from the above, that the factory bad block marker must be
>   searched within the 'data' region, and not in the usual OOB region.
> 
>   This seems to be similar to the gpmi-nand driver, yet I really find its
>   'bad block swapping' solution odd, so I'm trying to find something
>   cleaner.
> 
>   2. ECC modeling
> 
>   Although I've exposed some ECC information in the ECC layout, I'm still
>   not sure why is this needed, or if it's needed at all.
> 
> * About this patchset
> 
> This is based in l2-mtd's master branch and I've pushed a branch to our
> github in case anyone wants to test it:
> 
>   https://github.com/MISL-EBU-System-SW/mainline-public/tree/l2-mtd/upstream-nand-v2
> 
> Just as the previous, this series is complex and lengthy and any feedback will
> be highly appreciated as well as questions, suggestions or flames. Also, I hope
> our brave PXA regression tester Daniel Mack finds some time to give it a ride
> and report any issues. Daniel: I think owe you several beers already.
> 
> * About Mirabox testing
> 
> As this work is not considered completely stable, be extra careful when trying
> on the Mirabox. The Mirabox has the bootloader at NAND, and there's some risk
> to brick the board.
> 
> That said: I've been using the driver on my Mirabox for several days doing
> simple long-run NAND activity and everything worked fine.
> 
> If despite this you happen to brick the board, Willy Tarreau has provided
> excellent instructions to un-brick the Mirabox:
> 
>   http://1wt.eu/articles/mirabox-vs-guruplug/
> 
> Thanks!
> 
> Ezequiel Garcia (27):
>   clk: mvebu: Add Core Divider clock
>   ARM: mvebu: Add Core Divider clock device-tree binding
>   ARM: mvebu: Add a 2 GHz fixed-clock Armada 370/XP
>   ARM: mvebu: Add the core-divider clock to Armada 370/XP
>   mtd: nand: pxa3xx: Make config menu show supported platforms
>   mtd: nand: pxa3xx: Prevent sub-page writes
>   mtd: nand: pxa3xx: Early variant detection
>   mtd: nand: pxa3xx: Use chip->cmdfunc instead of the internal
>   mtd: nand: pxa3xx: Split FIFO size from to-be-read FIFO count
>   mtd: nand: pxa3xx: Replace host->page_size by mtd->writesize
>   mtd: nand: pxa3xx: Disable OOB on arbitrary length commands
>   mtd: nand: pxa3xx: Use a completion to signal device ready
>   mtd: nand: pxa3xx: Add bad block handling
>   mtd: nand: pxa3xx: Add driver-specific ECC BCH support
^^
This one and ...

>   mtd: nand: pxa3xx: Clear cmd buffer #3 (NDCB3) on command start
>   mtd: nand: pxa3xx: Add helper function to set page address
>   mtd: nand: pxa3xx: Remove READ0 switch/case falltrough
>   mtd: nand: pxa3xx: Split prepare_command_pool() in two stages
>   mtd: nand: pxa3xx: Move the data buffer clean to
>     prepare_start_command()
>   mtd: nand: pxa3xx: Fix SEQIN column address set
>   mtd: nand: pxa3xx: Add a read/write buffers markers
>   mtd: nand: pxa3xx: Introduce multiple page I/O support
^^^
.. this one seems to me like the most conflicting patches as
they extend the ECC, adding BCH. Could you review them and
provide any comments?

>   mtd: nand: pxa3xx: Add multiple chunk write support
>   mtd: nand: pxa3xx: Add ECC BCH correctable errors detection
>   ARM: mvebu: Add support for NAND controller in Armada 370/XP
>   ARM: mvebu: Enable NAND controller in Armada XP GP board
>   ARM: mvebu: Enable NAND controller in Armada 370 Mirabox
> 
>  .../bindings/clock/mvebu-corediv-clock.txt         |  19 +
>  arch/arm/boot/dts/armada-370-mirabox.dts           |  21 +
>  arch/arm/boot/dts/armada-370-xp.dtsi               |  26 +
>  arch/arm/boot/dts/armada-xp-gp.dts                 |   8 +
>  drivers/clk/mvebu/Kconfig                          |   5 +
>  drivers/clk/mvebu/Makefile                         |   1 +
>  drivers/clk/mvebu/clk-corediv.c                    | 223 +++++++
>  drivers/mtd/nand/Kconfig                           |   4 +-
>  drivers/mtd/nand/pxa3xx_nand.c                     | 686 ++++++++++++++++-----
>  include/linux/platform_data/mtd-nand-pxa3xx.h      |   3 +
>  10 files changed, 856 insertions(+), 140 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/mvebu-corediv-clock.txt
>  create mode 100644 drivers/clk/mvebu/clk-corediv.c
> 
> -- 
> 1.8.1.5
> 

Huang: It seems gpmi-nand driver has some similar quirks,
so I'd like if you could take some time to review my patches.

I realise that you might be busy with your own patches, but the
best way of having them cross-reviewed is by doing some review
on others work.

Thanks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From computersforpeace at gmail.com  Thu Oct 31 12:05:06 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 31 Oct 2013 12:05:06 -0400
Subject: [Rebase/PATCHv2] drivers: mtd: m25p80: Add quad read support.
In-Reply-To: <5271E423.9030506@ti.com>
References: <1383124802-25079-1-git-send-email-sourav.poddar@ti.com>
 <20131030231930.GD20059@norris.computersforpeace.net>
 <5271E423.9030506@ti.com>
Message-ID: <20131031160506.GC4700@norris.computersforpeace.net>

On Thu, Oct 31, 2013 at 10:31:23AM +0530, Sourav Poddar wrote:
> On Thursday 31 October 2013 04:49 AM, Brian Norris wrote:
> >On Wed, Oct 30, 2013 at 02:50:02PM +0530, Sourav Poddar wrote:
> >>@@ -95,6 +102,7 @@ struct m25p {
> >>  	u8			program_opcode;
> >>  	u8			*command;
> >>  	bool			fast_read;
> >>+	bool                    quad_read;
> >Did you have a response to my earlier suggestion that the fast_read and
> >quad_read fields be combined to a single field? This could easily be an
> >enum, and I think it could help some of the other code. It also wouldn't
> >require us to remember that quad_read takes precedence over fast_read
> >(which you do implicitly in this patch). And we can already foresee
> >additional switches needed if we add the DDR command types (Huang was
> >looking at this?), so we should just get it right now.
> >
> >You could, perhaps, make this two patches: one for converting the bool
> >to an enum, and the other for supporting quad-read.
> >
> I read that, and I was planning to take that as a seperate
> excercise, but yes I
> will cook this into two independent patches.

I think it is good to require the correct design principle (and
appropriate cleanup) before adding new features.

Brian


From computersforpeace at gmail.com  Thu Oct 31 13:52:00 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 31 Oct 2013 13:52:00 -0400
Subject: [PATCH] mtd: nand_bbt: kill NAND_BBT_SCANALLPAGES
In-Reply-To: <20131031153242.GB1092@localhost>
References: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
 <20131031102038.GA2391@localhost>
 <20131031152245.GB4700@norris.computersforpeace.net>
 <20131031153242.GB1092@localhost>
Message-ID: <20131031175200.GA7401@norris.computersforpeace.net>

On Thu, Oct 31, 2013 at 12:32:43PM -0300, Ezequiel Garcia wrote:
> But do we have any mechanism to scan a *particular*
> page?

No. But if we need it, we can develop a proper one. For instance, I
think a properly flexible approach could involve some kind of bitmap,
where each bit represents a particular page (e.g., a 32-bit bitmap where
the first 16 bits represent the first 16 pages and the last 16 represent
the last 16 pages).

I think, though, that modern NAND are converging to only a few types of
bad block marker locations, and our currently available flags (without
SCANALLPAGES) are sufficient.

Brian


From annulen at yandex.ru  Thu Oct 31 14:00:30 2013
From: annulen at yandex.ru (Konstantin Tokarev)
Date: Thu, 31 Oct 2013 22:00:30 +0400
Subject: Flashing UBIFS image to gluebi mtd
In-Reply-To: <20131031150844.GA1092@localhost>
References: <72811383227314@web24j.yandex.ru> <20131031150844.GA1092@localhost>
Message-ID: <16161383242430@web27h.yandex.ru>



31.10.2013, 19:08, "Ezequiel Garcia" <ezequiel.garcia at free-electrons.com>:
> Hi Konstantin,
>
> On Thu, Oct 31, 2013 at 05:48:34PM +0400, Konstantin Tokarev wrote:
>
>> ?I'm migrating rootfs of device from SquashFS on top of gluebi to UBIFS.
>
> Sounds like you could use ubiblock for that setup, which is suitable
> for squashfs, and completely independent of ubifs (thus less cpu and
> memory hungry and easier to setup).

Could you elaborate this a bit more? Do you mean that block device emultaion
layer on top of UBI + FS on top of that can work faster than UBIFS on top of
UBI?

Btw, I'm more interested in finding out in what way my UBIFS volume can be
broken in given scenario and how can I detect it (to reflash once again,
using UBI-aware updater this time).

-- 
Regards,
Konstantin


From computersforpeace at gmail.com  Thu Oct 31 14:22:33 2013
From: computersforpeace at gmail.com (Brian Norris)
Date: Thu, 31 Oct 2013 14:22:33 -0400
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <20131031155808.GB2468@localhost>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131031155808.GB2468@localhost>
Message-ID: <CAN8TOE-XdPgHykzzJtpkQ3ApTLXjZ+hCiAPpOBCZqa7uVt=kcA@mail.gmail.com>

On Thu, Oct 31, 2013 at 12:58:09PM -0300, Ezequiel Garcia wrote:
> Can we start discussing this patchset?
> I realize is a big series, but better starting sooner than later! :)

Yeah, I'm still figuring out prioritization here. I got a little
side-tracked on a few other patch series, some of which had
dependencies on each other. I will take a look at yours next.

...

> >   mtd: nand: pxa3xx: Introduce multiple page I/O support
> ^^^
> .. this one seems to me like the most conflicting patches as
> they extend the ECC, adding BCH. Could you review them and
> provide any comments?

Sure thing.

Brian


From ezequiel.garcia at free-electrons.com  Thu Oct 31 14:40:46 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 31 Oct 2013 15:40:46 -0300
Subject: Flashing UBIFS image to gluebi mtd
In-Reply-To: <16161383242430@web27h.yandex.ru>
References: <72811383227314@web24j.yandex.ru> <20131031150844.GA1092@localhost>
 <16161383242430@web27h.yandex.ru>
Message-ID: <20131031184045.GA2498@localhost>

On Thu, Oct 31, 2013 at 10:00:30PM +0400, Konstantin Tokarev wrote:
> 
> 
> 31.10.2013, 19:08, "Ezequiel Garcia" <ezequiel.garcia at free-electrons.com>:
> > Hi Konstantin,
> >
> > On Thu, Oct 31, 2013 at 05:48:34PM +0400, Konstantin Tokarev wrote:
> >
> >> ?I'm migrating rootfs of device from SquashFS on top of gluebi to UBIFS.
> >
> > Sounds like you could use ubiblock for that setup, which is suitable
> > for squashfs, and completely independent of ubifs (thus less cpu and
> > memory hungry and easier to setup).
> 
> Could you elaborate this a bit more? Do you mean that block device emultaion
> layer on top of UBI + FS on top of that can work faster than UBIFS on top of
> UBI?
> 

Given you provided no details, I'm not sure why you're migrating from squashfs
(which is a read-only, block oriented fs) to ubifs (which supports r/w on MTD).
But anyway, let me do this homework for you :-)

So, you had squashfs on top of gluebi, right? I guess you had this:

  mtd (plus your NAND driver) -> ubi -> gluebi/mtd -> mtdblock -> squashfs

On the other side, using ubiblock to emulate the block device you'd
end up with this:

  mtd (plus your NAND driver) -> ubi -> ubiblock -> squashfs

Which is less memory (cpu?) hungry than the first alternative.
The latest git branch also contained a non-cached option which
has shown some good behavior, given squashfs does its own caching.

But of course, this is _NOT_ a replacement for UBIFS, and using ubiblock
for R/W is strictly discouraged.

And here's the (already ancient) discussion:

http://lists.infradead.org/pipermail/linux-mtd/2012-November/045011.html

And the v2:
http://lists.infradead.org/pipermail/linux-mtd/2012-December/045274.html

I'll post the latest work as soon as I find some time, but you're free
to pursue your own research.

Hope it helps and best of lucks!
-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From ezequiel.garcia at free-electrons.com  Thu Oct 31 15:04:33 2013
From: ezequiel.garcia at free-electrons.com (Ezequiel Garcia)
Date: Thu, 31 Oct 2013 16:04:33 -0300
Subject: [PATCH] mtd: nand_bbt: kill NAND_BBT_SCANALLPAGES
In-Reply-To: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
References: <1383186575-31328-1-git-send-email-computersforpeace@gmail.com>
Message-ID: <20131031190432.GB2498@localhost>

On Wed, Oct 30, 2013 at 10:29:35PM -0400, Brian Norris wrote:
> Now that the last user of NAND_BBT_SCANALLPAGES has been removed, let's
> kill this peculiar BBT feature flag.
> 
> Signed-off-by: Brian Norris <computersforpeace at gmail.com>

Reviewed-by: Ezequiel Garcia <ezequiel.garcia at free-electrons.com>

> ---
>  Documentation/DocBook/mtdnand.tmpl |  2 --
>  drivers/mtd/nand/nand_bbt.c        | 37 +++----------------------------------
>  include/linux/mtd/bbm.h            |  2 --
>  3 files changed, 3 insertions(+), 38 deletions(-)
> 
> diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
> index a248f42a121e..cd11926e07c7 100644
> --- a/Documentation/DocBook/mtdnand.tmpl
> +++ b/Documentation/DocBook/mtdnand.tmpl
> @@ -1222,8 +1222,6 @@ in this page</entry>
>  #define NAND_BBT_VERSION	0x00000100
>  /* Create a bbt if none axists */
>  #define NAND_BBT_CREATE		0x00000200
> -/* Search good / bad pattern through all pages of a block */
> -#define NAND_BBT_SCANALLPAGES	0x00000400
>  /* Write bbt if neccecary */
>  #define NAND_BBT_WRITE		0x00001000
>  /* Read and write back block contents when writing bbt */
> diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
> index c75b6a7c6ea4..c0615d1526f9 100644
> --- a/drivers/mtd/nand/nand_bbt.c
> +++ b/drivers/mtd/nand/nand_bbt.c
> @@ -412,25 +412,6 @@ static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
>  	}
>  }
>  
> -/* Scan a given block full */
> -static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
> -			   loff_t offs, uint8_t *buf, size_t readlen,
> -			   int scanlen, int numpages)
> -{
> -	int ret, j;
> -
> -	ret = scan_read_oob(mtd, buf, offs, readlen);
> -	/* Ignore ECC errors when checking for BBM */
> -	if (ret && !mtd_is_bitflip_or_eccerr(ret))
> -		return ret;
> -
> -	for (j = 0; j < numpages; j++, buf += scanlen) {
> -		if (check_pattern(buf, scanlen, mtd->writesize, bd))
> -			return 1;
> -	}
> -	return 0;
> -}
> -
>  /* Scan a given block partially */
>  static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
>  			   loff_t offs, uint8_t *buf, int numpages)
> @@ -477,24 +458,17 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
>  	struct nand_bbt_descr *bd, int chip)
>  {
>  	struct nand_chip *this = mtd->priv;
> -	int i, numblocks, numpages, scanlen;
> +	int i, numblocks, numpages;
>  	int startblock;
>  	loff_t from;
> -	size_t readlen;
>  
>  	pr_info("Scanning device for bad blocks\n");
>  
> -	if (bd->options & NAND_BBT_SCANALLPAGES)
> -		numpages = 1 << (this->bbt_erase_shift - this->page_shift);
> -	else if (bd->options & NAND_BBT_SCAN2NDPAGE)
> +	if (bd->options & NAND_BBT_SCAN2NDPAGE)
>  		numpages = 2;
>  	else
>  		numpages = 1;
>  
> -	/* We need only read few bytes from the OOB area */
> -	scanlen = 0;
> -	readlen = bd->len;
> -
>  	if (chip == -1) {
>  		numblocks = mtd->size >> this->bbt_erase_shift;
>  		startblock = 0;
> @@ -519,12 +493,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
>  
>  		BUG_ON(bd->options & NAND_BBT_NO_OOB);
>  
> -		if (bd->options & NAND_BBT_SCANALLPAGES)
> -			ret = scan_block_full(mtd, bd, from, buf, readlen,
> -					      scanlen, numpages);
> -		else
> -			ret = scan_block_fast(mtd, bd, from, buf, numpages);
> -
> +		ret = scan_block_fast(mtd, bd, from, buf, numpages);
>  		if (ret < 0)
>  			return ret;
>  
> diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
> index 95fc482cef36..36bb6a503f19 100644
> --- a/include/linux/mtd/bbm.h
> +++ b/include/linux/mtd/bbm.h
> @@ -91,8 +91,6 @@ struct nand_bbt_descr {
>   * with NAND_BBT_CREATE.
>   */
>  #define NAND_BBT_CREATE_EMPTY	0x00000400
> -/* Search good / bad pattern through all pages of a block */
> -#define NAND_BBT_SCANALLPAGES	0x00000800
>  /* Write bbt if neccecary */
>  #define NAND_BBT_WRITE		0x00002000
>  /* Read and write back block contents when writing bbt */
> -- 
> 1.8.1.2
> 

-- 
Ezequiel Garc?a, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com


From tony at atomide.com  Thu Oct 31 17:23:49 2013
From: tony at atomide.com (Tony Lindgren)
Date: Thu, 31 Oct 2013 14:23:49 -0700
Subject: [PATCH v11 00/10] [PATCH v10 00/10] mtd:nand:omap2: clean-up
 of supported ECC schemes
In-Reply-To: <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>
References: <1382619026-4182-1-git-send-email-pekon@ti.com>
 <20131024135258.GC9958@localhost>
 <CAN8TOE_KQxW4-6KgjQDczyB31wmYB_y9Tirxa34GWQGgY39sNQ@mail.gmail.com>
Message-ID: <20131031212348.GK15154@atomide.com>

* Brian Norris <computersforpeace at gmail.com> [131029 21:00]:
> 
> Tony, you mentioned the DTS update in patch 8 going in via an ARM
> tree? This patch is not urgent, and it should probably wait until we
> know what release the rest of the series makes it into. This may
> depend on David Woodhouse's recommendation, but I'm not sure this
> series will have enough time baking in linux-next before entering
> mainline in 3.13 (the merge window is approaching).

Yes Benoit or I can apply that patch if Pekon pings me or resends
that patch when it's OK to merge it.

Regards,

Tony


From weiyj.lk at gmail.com  Thu Oct 31 20:16:18 2013
From: weiyj.lk at gmail.com (Wei Yongjun)
Date: Fri, 1 Nov 2013 08:16:18 +0800
Subject: [PATCH -next] mtd: nand: omap: fix error return code in
 omap_nand_probe()
Message-ID: <CAPgLHd8V06KzBcPmFywSfNxM0q6=s86xn-AdLKeY9h5JZ_nP7g@mail.gmail.com>

From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>

Fix to return a negative error code from the error handling
case instead of 0, as done elsewhere in this function.

Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
---
 drivers/mtd/nand/omap2.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index ec40b8d..f777250 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1953,7 +1953,8 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->ecc.read_page	= omap_read_page_bch;
 		nand_chip->ecc.write_page	= omap_write_page_bch;
 		/* This ECC scheme requires ELM H/W block */
-		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
+		err = is_elm_present(info, pdata->elm_of_node, BCH8_ECC);
+		if (err < 0) {
 			pr_err("nand: error: could not initialize ELM\n");
 			goto return_error;
 		}



From b32955 at freescale.com  Thu Oct 31 22:07:48 2013
From: b32955 at freescale.com (Huang Shijie)
Date: Fri, 1 Nov 2013 10:07:48 +0800
Subject: [PATCH v2 00/27] Armada 370/XP NAND support
In-Reply-To: <20131031155808.GB2468@localhost>
References: <1382137374-21251-1-git-send-email-ezequiel.garcia@free-electrons.com>
 <20131031155808.GB2468@localhost>
Message-ID: <52730CF4.5030000@freescale.com>

? 2013?10?31? 23:58, Ezequiel Garcia ??:
> Huang: It seems gpmi-nand driver has some similar quirks,
> so I'd like if you could take some time to review my patches.
i am busy recently. I will review your patch set tomorrow.

thanks
Huang Shijie



From jg1.han at samsung.com  Thu Oct 31 22:18:19 2013
From: jg1.han at samsung.com (Jingoo Han)
Date: Fri, 01 Nov 2013 11:18:19 +0900
Subject: [PATCH -next] mtd: nand: omap: fix error return code in
 omap_nand_probe()
In-Reply-To: <CAPgLHd8V06KzBcPmFywSfNxM0q6=s86xn-AdLKeY9h5JZ_nP7g@mail.gmail.com>
References: <CAPgLHd8V06KzBcPmFywSfNxM0q6=s86xn-AdLKeY9h5JZ_nP7g@mail.gmail.com>
Message-ID: <001101ced6a8$a18a2c80$e49e8580$%han@samsung.com>

On Friday, November 01, 2013 9:16 AM, Wei Yongjun wrote:
> 
> From: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> 
> Fix to return a negative error code from the error handling
> case instead of 0, as done elsewhere in this function.

Commit message is right? :-(

Best regards,
Jingoo Han

> 
> Signed-off-by: Wei Yongjun <yongjun_wei at trendmicro.com.cn>
> ---
>  drivers/mtd/nand/omap2.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
> index ec40b8d..f777250 100644
> --- a/drivers/mtd/nand/omap2.c
> +++ b/drivers/mtd/nand/omap2.c
> @@ -1953,7 +1953,8 @@ static int omap_nand_probe(struct platform_device *pdev)
>  		nand_chip->ecc.read_page	= omap_read_page_bch;
>  		nand_chip->ecc.write_page	= omap_write_page_bch;
>  		/* This ECC scheme requires ELM H/W block */
> -		if (is_elm_present(info, pdata->elm_of_node, BCH8_ECC) < 0) {
> +		err = is_elm_present(info, pdata->elm_of_node, BCH8_ECC);
> +		if (err < 0) {
>  			pr_err("nand: error: could not initialize ELM\n");
>  			goto return_error;
>  		}



From yousufsait at gmail.com  Thu Oct  3 09:54:36 2013
From: yousufsait at gmail.com (Yousuf Sait)
Date: Thu, 03 Oct 2013 16:54:36 -0000
Subject: Fwd: ubifs error
In-Reply-To: <CAHXsAqy=5fyKNYcNwOm1tiEeBnXvGbkfk67wxuqai_0K4Azv7w@mail.gmail.com>
References: <CAHXsAqxQJqjbCfsgjkd58FdCPNf7Du1+ET6ehsm83x5HHvXuzA@mail.gmail.com>
 <CAHXsAqyRsGorCoMF4LwmBdV4j_gtJhaHMMuq=Sogrig6wSeF3w@mail.gmail.com>
 <CAHXsAqy=5fyKNYcNwOm1tiEeBnXvGbkfk67wxuqai_0K4Azv7w@mail.gmail.com>
Message-ID: <CAHXsAqy-RV=reqvS0Rd93RHA9-wa=BV=3w1Lhd9wjWyT7OhnYw@mail.gmail.com>

Y

Hi All,

 I am working with ubifs partition of size 380MB on a nand of 512MB.
The volume is on a mtd device of size 400MB.
It was just working great but recently I noticed the following error,

UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): try_read_node: cannot read node type 1 from LEB
953:-1578055608, error -22
UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): do_readpage: cannot read page 1 of inode 2158, error -22
UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): try_read_node: cannot read node type 1 from LEB
953:-1578055608, error -22
UBIFS error (pid 508): ubifs_leb_read: reading -1578055608 bytes from
LEB 953:-1578055608 failed, error -22
UBIFS error (pid 508): do_readpage: cannot read page 1 of inode 2158, error -22

1.The strange thing is that the error vanished when I rebooted the
system. Thus I ruled out any nand corruption

2.Also there were no nand I/O errors in the log and this is a readonly
partition.

3.The library file was loaded with mmap() and the do_readpage() of ubi
code was exercised for page wise loading.

4.The sequence of the page aceeses from nand was pages 0, 21, 4, 5, 2
and 1, in which all of those reads succeded expect for page1.

5.While trying to read page1, it tried to read some -ve size with -ve
offset. There was a sanity check in ubi io code which failed and
didn't go till the nand driver.

6.Surprisingly both the offset and length values that ubi was trying
to read was the same value, -1578055608 (unsigned:  0xA1F0C848). The
actual value was found (from another instance of flashing) to be as
LEB 953:124408, key (2158, data, 1). That means LEB number was intact
while the offset and length got corrupted.

7. We have seen multiple instances of this issue but ubi giving error
for different files. In a different repro, I tried printing all the
zbr nodes with the one which had bad values. The other ones looks fine
expect for the corrupted one (zbr[5] in this case)

[   10.399113] UBIFS: zbr[0] lnum:353 off:26784 len:1641
[   10.399123] UBIFS: zbr[1] lnum:353 off:28432 len:1639
[   10.399133] UBIFS: zbr[2] lnum:353 off:30072 len:1738
[   10.399143] UBIFS: zbr[3] lnum:353 off:31816 len:1621
[   10.399152] UBIFS: zbr[4] lnum:353 off:33440 len:1594
[   10.399163] UBIFS: zbr[5] lnum:353 off:-1445529080 len:-1445529080
[   10.399173] UBIFS: zbr[6] lnum:353 off:36760 len:1788
[   10.399191] UBIFS: zbr[7] lnum:353 off:38552 len:1866
[   10.399209] UBIFS error (pid 87): ubifs_leb_read: reading
-1445529080 bytes from LEB 353:-1445529080 failed, error -22
[   10.399227] UBIFS: ubifs_tnc_locate: ubifs_tnc_read_node failed
key:200004f000000c3f err:-22 safely:1 lnum:off 353:-1445529080



The code I was using is based on K3.1 and I had no luck on reproducing
the issue with latest kernel (3.11). The repro of the issue is very
rare so i am not sure if the newer code fixed it is there still an
issue.

Tree head, with which I reproed the issue,


commit 016f1c54408b1e92e2e8087bfc05ca0a9c258513
Author: Michal Marek <mmarek at suse.cz>
Date:   Thu Aug 11 12:29:46 2011 +0200

UBIFS: not build debug messages with CONFIG_UBIFS_FS_DEBUG disabled
....


1) What could be wrong here ?
2) Any fix that had solved the issue in the newer kernel ?
3) I can try adding some debug information, any relevant info would be good

Y


