Use dma_alloc_noncoherent() instead to get the DMA buffer. [ 42.hyeyoo@xxxxxxxxx: Only keep label free. Remove unnecessary alignment checks. it's guaranteed by DMA API. Just use GFP_KERNEL as it's called in sleepable context. Specify its dma capability using dma_set_mask_and_coherent() ] Signed-off-by: Baoquan He <bhe@xxxxxxxxxx> Signed-off-by: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> Cc: Pierre Ossman <pierre@xxxxxxxxx> Cc: Ulf Hansson <ulf.hansson@xxxxxxxxxx> Cc: linux-mmc@xxxxxxxxxxxxxxx --- drivers/mmc/host/wbsd.c | 45 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index 67ecd342fe5f..50b0197583c7 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c @@ -1366,55 +1366,28 @@ static void wbsd_request_dma(struct wbsd_host *host, int dma) if (request_dma(dma, DRIVER_NAME)) goto err; + dma_set_mask_and_coherent(mmc_dev(host->mmc), DMA_BIT_MASK(24)); + /* * We need to allocate a special buffer in * order for ISA to be able to DMA to it. */ - host->dma_buffer = kmalloc(WBSD_DMA_SIZE, - GFP_NOIO | GFP_DMA | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + host->dma_buffer = dma_alloc_noncoherent(mmc_dev(host->mmc), + WBSD_DMA_SIZE, &host->dma_addr, + DMA_BIDIRECTIONAL, + GFP_KERNEL); if (!host->dma_buffer) goto free; - /* - * Translate the address to a physical address. - */ - host->dma_addr = dma_map_single(mmc_dev(host->mmc), host->dma_buffer, - WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(mmc_dev(host->mmc), host->dma_addr)) - goto kfree; - - /* - * ISA DMA must be aligned on a 64k basis. - */ - if ((host->dma_addr & 0xffff) != 0) - goto unmap; - /* - * ISA cannot access memory above 16 MB. - */ - else if (host->dma_addr >= 0x1000000) - goto unmap; - host->dma = dma; return; -unmap: - /* - * If we've gotten here then there is some kind of alignment bug - */ - BUG_ON(1); - - dma_unmap_single(mmc_dev(host->mmc), host->dma_addr, - WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); - host->dma_addr = 0; - -kfree: - kfree(host->dma_buffer); - host->dma_buffer = NULL; - free: + dma_free_noncoherent(mmc_dev(host->mmc), WBSD_DMA_SIZE, host->dma_buffer, + host->dma_addr, DMA_BIDIRECTIONAL); + host->dma_buffer = NULL; free_dma(dma); - err: pr_warn(DRIVER_NAME ": Unable to allocate DMA %d - falling back on FIFO\n", dma); -- 2.17.2