diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2017-06-13 15:45:48 +0200 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-06-20 09:14:53 +0200 |
commit | 7d370b2c255612569818134ae0a6d0e46eabfe8b (patch) | |
tree | 99e1e05b9a16623fa8f382c18340cbedb511cdc5 /drivers/mtd/nand/denali.c | |
parent | mtd: nand: denali: skip driver internal bounce buffer when possible (diff) | |
download | linux-7d370b2c255612569818134ae0a6d0e46eabfe8b.tar.xz linux-7d370b2c255612569818134ae0a6d0e46eabfe8b.zip |
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 <yamada.masahiro@socionext.com>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Cc: Lars-Peter Clausen <lars@metafoo.de>
Acked-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'drivers/mtd/nand/denali.c')
-rw-r--r-- | drivers/mtd/nand/denali.c | 26 |
1 files 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 <linux/mutex.h> #include <linux/mtd/mtd.h> #include <linux/module.h> +#include <linux/slab.h> #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); |