Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 657a77fa authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by Dan Williams
Browse files

dmaengine: Move all map_sg/unmap_sg for slave channel to its client



Dan Williams wrote:
... DMA-slave clients request specific channels and know the hardware
details at a low level, so it should not be too high an expectation to
push dma mapping responsibility to the client.

Also this patch includes DMA_COMPL_{SRC,DEST}_UNMAP_SINGLE support for
dw_dmac driver.

Acked-by: default avatarMaciej Sosnowski <maciej.sosnowski@intel.com>
Acked-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent bbea0b6e
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -253,26 +253,29 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
	list_move(&desc->desc_node, &atchan->free_list);

	/* unmap dma addresses */
	if (!atchan->chan_common.private) {
		struct device *parent = chan2parent(&atchan->chan_common);
		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
			dma_unmap_single(chan2parent(&atchan->chan_common),
				dma_unmap_single(parent,
						desc->lli.daddr,
						desc->len, DMA_FROM_DEVICE);
			else
			dma_unmap_page(chan2parent(&atchan->chan_common),
				dma_unmap_page(parent,
						desc->lli.daddr,
						desc->len, DMA_FROM_DEVICE);
		}
		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
			dma_unmap_single(chan2parent(&atchan->chan_common),
				dma_unmap_single(parent,
						desc->lli.saddr,
						desc->len, DMA_TO_DEVICE);
			else
			dma_unmap_page(chan2parent(&atchan->chan_common),
				dma_unmap_page(parent,
						desc->lli.saddr,
						desc->len, DMA_TO_DEVICE);
		}
	}

	/*
	 * The API requires that no submissions are done from a
@@ -647,8 +650,6 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,

	reg_width = atslave->reg_width;

	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);

	ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;

+19 −12
Original line number Diff line number Diff line
@@ -212,16 +212,25 @@ dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc)
	list_splice_init(&desc->tx_list, &dwc->free_list);
	list_move(&desc->desc_node, &dwc->free_list);

	/*
	 * We use dma_unmap_page() regardless of how the buffers were
	 * mapped before they were submitted...
	 */
	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP))
		dma_unmap_page(chan2parent(&dwc->chan), desc->lli.dar,
	if (!dwc->chan.private) {
		struct device *parent = chan2parent(&dwc->chan);
		if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
			if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
				dma_unmap_single(parent, desc->lli.dar,
						desc->len, DMA_FROM_DEVICE);
	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP))
		dma_unmap_page(chan2parent(&dwc->chan), desc->lli.sar,
			else
				dma_unmap_page(parent, desc->lli.dar,
						desc->len, DMA_FROM_DEVICE);
		}
		if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
			if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
				dma_unmap_single(parent, desc->lli.sar,
						desc->len, DMA_TO_DEVICE);
			else
				dma_unmap_page(parent, desc->lli.sar,
						desc->len, DMA_TO_DEVICE);
		}
	}

	/*
	 * The API requires that no submissions are done from a
@@ -658,8 +667,6 @@ dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
	reg_width = dws->reg_width;
	prev = first = NULL;

	sg_len = dma_map_sg(chan2parent(chan), sgl, sg_len, direction);

	switch (direction) {
	case DMA_TO_DEVICE:
		ctllo = (DWC_DEFAULT_CTLLO
+8 −1
Original line number Diff line number Diff line
@@ -576,6 +576,7 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
	struct scatterlist		*sg;
	unsigned int			i;
	enum dma_data_direction		direction;
	unsigned int			sglen;

	/*
	 * We don't do DMA on "complex" transfers, i.e. with
@@ -605,11 +606,14 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
	else
		direction = DMA_TO_DEVICE;

	sglen = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, direction);
	if (sglen != data->sg_len)
		goto unmap_exit;
	desc = chan->device->device_prep_slave_sg(chan,
			data->sg, data->sg_len, direction,
			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
	if (!desc)
		return -ENOMEM;
		goto unmap_exit;

	host->dma.data_desc = desc;
	desc->callback = atmci_dma_complete;
@@ -620,6 +624,9 @@ atmci_submit_data_dma(struct atmel_mci *host, struct mmc_data *data)
	chan->device->device_issue_pending(chan);

	return 0;
unmap_exit:
	dma_unmap_sg(&host->pdev->dev, data->sg, sglen, direction);
	return -ENOMEM;
}

#else /* CONFIG_MMC_ATMELMCI_DMA */