From 7d370b2c255612569818134ae0a6d0e46eabfe8b Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 13 Jun 2017 22:45:48 +0900 Subject: [PATCH] mtd: nand: denali: use non-managed kmalloc() for DMA buffer As Russell and Lars stated in the discussion [1], using devm_k*alloc() with DMA is not a good idea. Let's use kmalloc (not kzalloc because no need for zero-out). Also, allocate the buffer as late as possible because it must be freed for any error that follows. [1] https://lkml.org/lkml/2017/3/8/693 Signed-off-by: Masahiro Yamada Cc: Russell King Cc: Lars-Peter Clausen Acked-by: Robin Murphy Signed-off-by: Boris Brezillon --- drivers/mtd/nand/denali.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index ec5fc8da5f9a..bb2da2fd069e 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "denali.h" @@ -1352,13 +1353,6 @@ int denali_init(struct denali_nand_info *denali) if (ret) goto disable_irq; - denali->buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize, - GFP_KERNEL); - if (!denali->buf) { - ret = -ENOMEM; - goto disable_irq; - } - if (ioread32(denali->flash_reg + FEATURES) & FEATURES__DMA) denali->dma_avail = 1; @@ -1443,17 +1437,30 @@ int denali_init(struct denali_nand_info *denali) if (ret) goto disable_irq; + /* + * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not + * use devm_kmalloc() because the memory allocated by devm_ does not + * guarantee DMA-safe alignment. + */ + denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); + if (!denali->buf) { + ret = -ENOMEM; + goto disable_irq; + } + ret = nand_scan_tail(mtd); if (ret) - goto disable_irq; + goto free_buf; ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(denali->dev, "Failed to register MTD: %d\n", ret); - goto disable_irq; + goto free_buf; } return 0; +free_buf: + kfree(denali->buf); disable_irq: denali_disable_irq(denali); @@ -1467,6 +1474,7 @@ void denali_remove(struct denali_nand_info *denali) struct mtd_info *mtd = nand_to_mtd(&denali->nand); nand_release(mtd); + kfree(denali->buf); denali_disable_irq(denali); } EXPORT_SYMBOL(denali_remove);