dmaengine: dw: introduce generic filter function
The introduced filter function would be reused in the ACPI and DT cases since in those cases we have to apply mandatory data to the requested channel. Thus, patch moves platform driver to use it in that case. The function unlikely can't be used by users of the driver due to an implicit dependency to the dw_dmac_core module. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:

committed by
Vinod Koul

parent
8950052029
commit
4d130de20c
@@ -25,74 +25,49 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct dw_dma_of_filter_args {
|
||||
struct dw_dma *dw;
|
||||
unsigned int req;
|
||||
unsigned int src;
|
||||
unsigned int dst;
|
||||
};
|
||||
|
||||
static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma_of_filter_args *fargs = param;
|
||||
|
||||
/* Ensure the device matches our channel */
|
||||
if (chan->device != &fargs->dw->dma)
|
||||
return false;
|
||||
|
||||
dwc->src_id = fargs->req;
|
||||
dwc->dst_id = fargs->req;
|
||||
dwc->src_master = fargs->src;
|
||||
dwc->dst_master = fargs->dst;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
|
||||
struct of_dma *ofdma)
|
||||
{
|
||||
struct dw_dma *dw = ofdma->of_dma_data;
|
||||
struct dw_dma_of_filter_args fargs = {
|
||||
.dw = dw,
|
||||
struct dw_dma_slave slave = {
|
||||
.dma_dev = dw->dma.dev,
|
||||
};
|
||||
dma_cap_mask_t cap;
|
||||
|
||||
if (dma_spec->args_count != 3)
|
||||
return NULL;
|
||||
|
||||
fargs.req = dma_spec->args[0];
|
||||
fargs.src = dma_spec->args[1];
|
||||
fargs.dst = dma_spec->args[2];
|
||||
slave.src_id = dma_spec->args[0];
|
||||
slave.dst_id = dma_spec->args[0];
|
||||
slave.src_master = dma_spec->args[1];
|
||||
slave.dst_master = dma_spec->args[2];
|
||||
|
||||
if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
|
||||
fargs.src >= dw->nr_masters ||
|
||||
fargs.dst >= dw->nr_masters))
|
||||
if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
|
||||
slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
|
||||
slave.src_master >= dw->nr_masters ||
|
||||
slave.dst_master >= dw->nr_masters))
|
||||
return NULL;
|
||||
|
||||
dma_cap_zero(cap);
|
||||
dma_cap_set(DMA_SLAVE, cap);
|
||||
|
||||
/* TODO: there should be a simpler way to do this */
|
||||
return dma_request_channel(cap, dw_dma_of_filter, &fargs);
|
||||
return dma_request_channel(cap, dw_dma_filter, &slave);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
|
||||
{
|
||||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct acpi_dma_spec *dma_spec = param;
|
||||
struct dw_dma_slave slave = {
|
||||
.dma_dev = dma_spec->dev,
|
||||
.src_id = dma_spec->slave_id,
|
||||
.dst_id = dma_spec->slave_id,
|
||||
.src_master = 1,
|
||||
.dst_master = 0,
|
||||
};
|
||||
|
||||
if (chan->device->dev != dma_spec->dev ||
|
||||
chan->chan_id != dma_spec->chan_id)
|
||||
return false;
|
||||
|
||||
dwc->src_id = dma_spec->slave_id;
|
||||
dwc->dst_id = dma_spec->slave_id;
|
||||
dwc->src_master = dwc_get_sms(NULL);
|
||||
dwc->dst_master = dwc_get_dms(NULL);
|
||||
|
||||
return true;
|
||||
return dw_dma_filter(chan, &slave);
|
||||
}
|
||||
|
||||
static void dw_dma_acpi_controller_register(struct dw_dma *dw)
|
||||
|
Reference in New Issue
Block a user