Commit 794a0f7b authored by Serge Semin's avatar Serge Semin Committed by Bjorn Helgaas

dmaengine: dw-edma: Drop dma_slave_config.direction field usage

The dma_slave_config.direction field usage in the DW eDMA driver was
introduced by bd96f1b2 ("dmaengine: dw-edma: support local dma device
transfer semantics"). Mainly the change introduced there was correct
(indeed DEV_TO_MEM means using RD-channel and MEM_TO_DEV - WR-channel for
the case of having eDMA accessed locally from CPU/Application side), but
providing an additional MEM_TO_MEM/DEV_TO_DEV-based semantics was quite
redundant if not to say potentially harmful (when it comes to removing the
denoted field). First of all since the dma_slave_config.direction field has
been marked as obsolete (see [1] and the struct dma_slave_config [2]) and
will be discarded in future, using it especially in a non-standard way is
discouraged. Secondly in accordance with the commit denoted above the
default dw_edma_device_transfer() semantics has been changed despite what
its message said. So claiming that the method was left backward compatible
was wrong.

Fix the problems denoted above and simplify the dw_edma_device_transfer()
method by dropping the parsing of the DMA-channel direction field. Instead
of having that implicit dma_slave_config.direction field semantic, use the
recently added DW_EDMA_CHIP_LOCAL flag to distinguish between the local and
remote DW eDMA setups thus preserving support for both cases. Add an ASCII
figure to clarify the situation.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/driver-api/dmaengine/provider.rst?id=v5.18#n478
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/dmaengine.h?id=v5.18#n389

[bhelgaas: convert references to specific URLs]
Co-developed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20220524152159.2370739-6-Frank.Li@nxp.comTested-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: default avatarFrank Li <Frank.Li@nxp.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-By: default avatarVinod Koul <vkoul@kernel.org>
parent 6951ee96
......@@ -339,20 +339,39 @@ dw_edma_device_transfer(struct dw_edma_transfer *xfer)
if (!chan->configured)
return NULL;
switch (chan->config.direction) {
case DMA_DEV_TO_MEM: /* local DMA */
if (dir == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_READ)
break;
return NULL;
case DMA_MEM_TO_DEV: /* local DMA */
if (dir == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_WRITE)
break;
/*
* Local Root Port/End-point Remote End-point
* +-----------------------+ PCIe bus +----------------------+
* | | +-+ | |
* | DEV_TO_MEM Rx Ch <----+ +---+ Tx Ch DEV_TO_MEM |
* | | | | | |
* | MEM_TO_DEV Tx Ch +----+ +---> Rx Ch MEM_TO_DEV |
* | | +-+ | |
* +-----------------------+ +----------------------+
*
* 1. Normal logic:
* If eDMA is embedded into the DW PCIe RP/EP and controlled from the
* CPU/Application side, the Rx channel (EDMA_DIR_READ) will be used
* for the device read operations (DEV_TO_MEM) and the Tx channel
* (EDMA_DIR_WRITE) - for the write operations (MEM_TO_DEV).
*
* 2. Inverted logic:
* If eDMA is embedded into a Remote PCIe EP and is controlled by the
* MWr/MRd TLPs sent from the CPU's PCIe host controller, the Tx
* channel (EDMA_DIR_WRITE) will be used for the device read operations
* (DEV_TO_MEM) and the Rx channel (EDMA_DIR_READ) - for the write
* operations (MEM_TO_DEV).
*
* It is the client driver responsibility to choose a proper channel
* for the DMA transfers.
*/
if (chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
if ((chan->dir == EDMA_DIR_READ && dir != DMA_DEV_TO_MEM) ||
(chan->dir == EDMA_DIR_WRITE && dir != DMA_MEM_TO_DEV))
return NULL;
default: /* remote DMA */
if (dir == DMA_MEM_TO_DEV && chan->dir == EDMA_DIR_READ)
break;
if (dir == DMA_DEV_TO_MEM && chan->dir == EDMA_DIR_WRITE)
break;
} else {
if ((chan->dir == EDMA_DIR_WRITE && dir != DMA_DEV_TO_MEM) ||
(chan->dir == EDMA_DIR_READ && dir != DMA_MEM_TO_DEV))
return NULL;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment