[U-Boot,V3] NAND: Allow per-buffer allocation

Submitted by Marek Vasut on Aug. 10, 2011, 2:13 a.m.

Details

Message ID 1312942403-7977-1-git-send-email-marek.vasut@gmail.com
State Superseded
Headers show

Commit Message

Marek Vasut Aug. 10, 2011, 2:13 a.m.
Don't allocate NAND buffers as one block, but allocate them separately. This can
be beneficial for example for systems, which need DMA buffers to be aligned.
With this patch, such systems can allocate aligned buffers and avoid memcpy()ing
data in place.

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
 drivers/mtd/nand/nand_base.c |   30 +++++++++++++++++++++++-------
 include/linux/mtd/nand.h     |    7 ++++---
 2 files changed, 27 insertions(+), 10 deletions(-)

V2: Fix the chip->buffers->buffer condition

V3: Fix compiler warning due to bad cast in chip->buffers->buffer and patch
description

Patch hide | download patch | download mbox

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1a95a91..a5f872e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2749,13 +2749,27 @@  int nand_scan_ident(struct mtd_info *mtd, int maxchips,
  */
 int nand_scan_tail(struct mtd_info *mtd)
 {
-	int i;
+	int i, bufsize;
+	uint8_t *buf;
 	struct nand_chip *chip = mtd->priv;
 
-	if (!(chip->options & NAND_OWN_BUFFERS))
-		chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);
-	if (!chip->buffers)
-		return -ENOMEM;
+	if (!(chip->options & NAND_OWN_BUFFERS)) {
+		chip->buffers = malloc(sizeof(struct nand_buffers));
+		if (!chip->buffers)
+			return -ENOMEM;
+
+		bufsize = NAND_MAX_PAGESIZE + (3 * NAND_MAX_OOBSIZE);
+		buf = malloc(bufsize);
+		if (!buf) {
+			free(chip->buffers);
+			return -ENOMEM;
+		}
+
+		chip->buffers->buffer = buf;
+		chip->buffers->ecccalc = buf;
+		chip->buffers->ecccode = buf + NAND_MAX_OOBSIZE;
+		chip->buffers->databuf = buf + (2 * NAND_MAX_OOBSIZE);
+	}
 
 	/* Set the internal oob buffer location, just after the page data */
 	chip->oob_poi = chip->buffers->databuf + mtd->writesize;
@@ -2996,6 +3010,8 @@  void nand_release(struct mtd_info *mtd)
 
 	/* Free bad block table memory */
 	kfree(chip->bbt);
-	if (!(chip->options & NAND_OWN_BUFFERS))
-		kfree(chip->buffers);
+	if (!(chip->options & NAND_OWN_BUFFERS)) {
+		free(chip->buffers->buffer);
+		free(chip->buffers);
+	}
 }
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 987a2ec..c3449a9 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -370,9 +370,10 @@  struct nand_ecc_ctrl {
  * consecutive order.
  */
 struct nand_buffers {
-	uint8_t	ecccalc[NAND_MAX_OOBSIZE];
-	uint8_t	ecccode[NAND_MAX_OOBSIZE];
-	uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];
+	uint8_t *buffer;
+	uint8_t	*ecccalc;
+	uint8_t	*ecccode;
+	uint8_t *databuf;
 };
 
 /**