
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
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; };
/**