diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 5c90941f31d9..78359baee369 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -465,8 +465,6 @@ static void sdhci_adma_mark_end(void *desc) static int sdhci_adma_table_pre(struct sdhci_host *host, struct mmc_data *data) { - int direction; - void *desc; void *align; dma_addr_t addr; @@ -483,20 +481,9 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, * We currently guess that it is LE. */ - if (data->flags & MMC_DATA_READ) - direction = DMA_FROM_DEVICE; - else - direction = DMA_TO_DEVICE; - - host->align_addr = dma_map_single(mmc_dev(host->mmc), - host->align_buffer, host->align_buffer_sz, direction); - if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) - goto fail; - BUG_ON(host->align_addr & SDHCI_ADMA2_MASK); - host->sg_count = sdhci_pre_dma_transfer(host, data); if (host->sg_count < 0) - goto unmap_align; + return -EINVAL; desc = host->adma_table; align = host->align_buffer; @@ -570,22 +557,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, /* nop, end, valid */ sdhci_adma_write_desc(host, desc, 0, 0, ADMA2_NOP_END_VALID); } - - /* - * Resync align buffer as we might have changed it. - */ - if (data->flags & MMC_DATA_WRITE) { - dma_sync_single_for_device(mmc_dev(host->mmc), - host->align_addr, host->align_buffer_sz, direction); - } - return 0; - -unmap_align: - dma_unmap_single(mmc_dev(host->mmc), host->align_addr, - host->align_buffer_sz, direction); -fail: - return -EINVAL; } static void sdhci_adma_table_post(struct sdhci_host *host, @@ -605,9 +577,6 @@ static void sdhci_adma_table_post(struct sdhci_host *host, else direction = DMA_TO_DEVICE; - dma_unmap_single(mmc_dev(host->mmc), host->align_addr, - host->align_buffer_sz, direction); - /* Do a quick scan of the SG list for any unaligned mappings */ has_unaligned = false; for_each_sg(data->sg, sg, host->sg_count, i) @@ -2985,14 +2954,21 @@ int sdhci_add_host(struct sdhci_host *host) &host->adma_addr, GFP_KERNEL); host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN; - host->align_buffer = kmalloc(host->align_buffer_sz, GFP_KERNEL); + host->align_buffer = dma_alloc_coherent(mmc_dev(mmc), + host->align_buffer_sz, + &host->align_addr, + GFP_KERNEL); if (!host->adma_table || !host->align_buffer) { if (host->adma_table) dma_free_coherent(mmc_dev(mmc), host->adma_table_sz, host->adma_table, host->adma_addr); - kfree(host->align_buffer); + if (host->align_buffer) + dma_free_coherent(mmc_dev(mmc), + host->align_buffer_sz, + host->align_buffer, + host->align_addr); pr_warn("%s: Unable to allocate ADMA buffers - falling back to standard DMA\n", mmc_hostname(mmc)); host->flags &= ~SDHCI_USE_ADMA; @@ -3004,10 +2980,14 @@ int sdhci_add_host(struct sdhci_host *host) host->flags &= ~SDHCI_USE_ADMA; dma_free_coherent(mmc_dev(mmc), host->adma_table_sz, host->adma_table, host->adma_addr); - kfree(host->align_buffer); + dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz, + host->align_buffer, host->align_addr); host->adma_table = NULL; host->align_buffer = NULL; } + + /* dma_alloc_coherent returns page aligned and sized buffers */ + BUG_ON(host->align_addr & SDHCI_ADMA2_MASK); } /* @@ -3470,7 +3450,9 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) if (host->adma_table) dma_free_coherent(mmc_dev(mmc), host->adma_table_sz, host->adma_table, host->adma_addr); - kfree(host->align_buffer); + if (host->align_buffer) + dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz, + host->align_buffer, host->align_addr); host->adma_table = NULL; host->align_buffer = NULL;