From: David Brownell <[email protected]> Allocate and free (NR_SG - 1) parameter RAM slots, and make max_hw_segs reflect that. This is a NOP until NR_SG is changed, at which point those slots *need* to be used.
Unmapping scatterlists must use the original scatterlist length, not the length after mapping. (But they won't currently differ.) Signed-off-by: David Brownell <[email protected]> --- drivers/mmc/host/davinci_mmc.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -201,6 +201,8 @@ struct mmc_davinci_host { */ struct edmacc_param tx_template; struct edmacc_param rx_template; + unsigned n_link; + u8 links[NR_SG - 1]; /* For PIO we walk scatterlists one segment at a time. */ unsigned int sg_len; @@ -569,16 +571,21 @@ static int mmc_davinci_start_dma_transfe static void __init_or_module davinci_release_dma_channels(struct mmc_davinci_host *host) { + unsigned i; + if (!host->use_dma) return; + for (i = 0; i < host->n_link; i++) + edma_free_slot(host->links[i]); + edma_free_channel(host->txdma); edma_free_channel(host->rxdma); } static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host) { - int r; + int r, i; /* Acquire master DMA write channel */ r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host, @@ -600,6 +607,20 @@ static int __init davinci_acquire_dma_ch } mmc_davinci_dma_setup(host, false, &host->rx_template); + /* Allocate parameter RAM slots, which will later be bound to a + * channel as needed to handle a scatterlist. + */ + for (i = 0; i < ARRAY_SIZE(host->links); i++) { + r = edma_alloc_slot(EDMA_SLOT_ANY); + if (r < 0) { + dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n", + r); + break; + } + host->links[i] = r; + } + host->n_link = i; + return 0; free_master_write: @@ -801,7 +822,7 @@ mmc_davinci_xfer_done(struct mmc_davinci if (host->do_dma) { davinci_abort_dma(host); - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_len, + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, (data->flags & MMC_DATA_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); @@ -1117,8 +1138,11 @@ static int __init davinci_mmcsd_probe(st } mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - /* with no iommu coalescing pages, each phys_seg is a hw_seg */ - mmc->max_hw_segs = NR_SG; + /* With no iommu coalescing pages, each phys_seg is a hw_seg. + * Each hw_seg uses one EDMA parameter RAM slot, always one + * channel and then usually some linked slots. + */ + mmc->max_hw_segs = 1 + host->n_link; mmc->max_phys_segs = mmc->max_hw_segs; /* EDMA limit per hw segment (one or two MBytes) */ _______________________________________________ Davinci-linux-open-source mailing list [email protected] http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
