diff options
| author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2015-12-14 15:47:40 -0500 |
|---|---|---|
| committer | Vinod Koul <vinod.koul@intel.com> | 2015-12-18 00:47:26 -0500 |
| commit | a8135d0d79e9d0ad3a4ff494fceeaae838becf38 (patch) | |
| tree | 3aba1f9650cf172838575013e74ce905c67418fc /Documentation/dmaengine | |
| parent | 7bd903c5ca47fde5ad52370a47776491813c772e (diff) | |
dmaengine: core: Introduce new, universal API to request a channel
The two API function can cover most, if not all current APIs used to
request a channel. With minimal effort dmaengine drivers, platforms and
dmaengine user drivers can be converted to use the two function.
struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask);
To request any channel matching with the requested capabilities, can be
used to request channel for memcpy, memset, xor, etc where no hardware
synchronization is needed.
struct dma_chan *dma_request_chan(struct device *dev, const char *name);
To request a slave channel. The dma_request_chan() will try to find the
channel via DT, ACPI or in case if the kernel booted in non DT/ACPI mode
it will use a filter lookup table and retrieves the needed information from
the dma_slave_map provided by the DMA drivers.
This legacy mode needs changes in platform code, in dmaengine drivers and
finally the dmaengine user drivers can be converted:
For each dmaengine driver an array of DMA device, slave and the parameter
for the filter function needs to be added:
static const struct dma_slave_map da830_edma_map[] = {
{ "davinci-mcasp.0", "rx", EDMA_FILTER_PARAM(0, 0) },
{ "davinci-mcasp.0", "tx", EDMA_FILTER_PARAM(0, 1) },
{ "davinci-mcasp.1", "rx", EDMA_FILTER_PARAM(0, 2) },
{ "davinci-mcasp.1", "tx", EDMA_FILTER_PARAM(0, 3) },
{ "davinci-mcasp.2", "rx", EDMA_FILTER_PARAM(0, 4) },
{ "davinci-mcasp.2", "tx", EDMA_FILTER_PARAM(0, 5) },
{ "spi_davinci.0", "rx", EDMA_FILTER_PARAM(0, 14) },
{ "spi_davinci.0", "tx", EDMA_FILTER_PARAM(0, 15) },
{ "da830-mmc.0", "rx", EDMA_FILTER_PARAM(0, 16) },
{ "da830-mmc.0", "tx", EDMA_FILTER_PARAM(0, 17) },
{ "spi_davinci.1", "rx", EDMA_FILTER_PARAM(0, 18) },
{ "spi_davinci.1", "tx", EDMA_FILTER_PARAM(0, 19) },
};
This information is going to be needed by the dmaengine driver, so
modification to the platform_data is needed, and the driver map should be
added to the pdata of the DMA driver:
da8xx_edma0_pdata.slave_map = da830_edma_map;
da8xx_edma0_pdata.slavecnt = ARRAY_SIZE(da830_edma_map);
The DMA driver then needs to configure the needed device -> filter_fn
mapping before it registers with dma_async_device_register() :
ecc->dma_slave.filter_map.map = info->slave_map;
ecc->dma_slave.filter_map.mapcnt = info->slavecnt;
ecc->dma_slave.filter_map.fn = edma_filter_fn;
When neither DT or ACPI lookup is available the dma_request_chan() will
try to match the requester's device name with the filter_map's list of
device names, when a match found it will use the information from the
dma_slave_map to get the channel with the dma_get_channel() internal
function.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'Documentation/dmaengine')
| -rw-r--r-- | Documentation/dmaengine/client.txt | 23 |
1 files changed, 6 insertions, 17 deletions
diff --git a/Documentation/dmaengine/client.txt b/Documentation/dmaengine/client.txt index 11fb87ff6cd0..4b04d8988708 100644 --- a/Documentation/dmaengine/client.txt +++ b/Documentation/dmaengine/client.txt | |||
| @@ -22,25 +22,14 @@ The slave DMA usage consists of following steps: | |||
| 22 | Channel allocation is slightly different in the slave DMA context, | 22 | Channel allocation is slightly different in the slave DMA context, |
| 23 | client drivers typically need a channel from a particular DMA | 23 | client drivers typically need a channel from a particular DMA |
| 24 | controller only and even in some cases a specific channel is desired. | 24 | controller only and even in some cases a specific channel is desired. |
| 25 | To request a channel dma_request_channel() API is used. | 25 | To request a channel dma_request_chan() API is used. |
| 26 | 26 | ||
| 27 | Interface: | 27 | Interface: |
| 28 | struct dma_chan *dma_request_channel(dma_cap_mask_t mask, | 28 | struct dma_chan *dma_request_chan(struct device *dev, const char *name); |
| 29 | dma_filter_fn filter_fn, | 29 | |
| 30 | void *filter_param); | 30 | Which will find and return the 'name' DMA channel associated with the 'dev' |
| 31 | where dma_filter_fn is defined as: | 31 | device. The association is done via DT, ACPI or board file based |
| 32 | typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param); | 32 | dma_slave_map matching table. |
| 33 | |||
| 34 | The 'filter_fn' parameter is optional, but highly recommended for | ||
| 35 | slave and cyclic channels as they typically need to obtain a specific | ||
| 36 | DMA channel. | ||
| 37 | |||
| 38 | When the optional 'filter_fn' parameter is NULL, dma_request_channel() | ||
| 39 | simply returns the first channel that satisfies the capability mask. | ||
| 40 | |||
| 41 | Otherwise, the 'filter_fn' routine will be called once for each free | ||
| 42 | channel which has a capability in 'mask'. 'filter_fn' is expected to | ||
| 43 | return 'true' when the desired DMA channel is found. | ||
| 44 | 33 | ||
| 45 | A channel allocated via this interface is exclusive to the caller, | 34 | A channel allocated via this interface is exclusive to the caller, |
| 46 | until dma_release_channel() is called. | 35 | until dma_release_channel() is called. |
