/*
* Initialise the DMAC channels.
* Make a local wrapper to hold required data
*/
static int pl08x_dma_enumerate_channels(void)
{
int dma_chan;
struct pl08x_dma_chan *local_chan;
dma_cap_set(DMA_MEMCPY, dmac.cap_mask);
dma_cap_set(DMA_SLAVE, dmac.cap_mask);
if (dmac.chancnt)
dev_err(&pd.dmac->dev, "%s - chancnt already set\n", __func__);
INIT_LIST_HEAD(&dmac.channels);
for (dma_chan = 0; dma_chan < MAX_DMA_CHANNELS; dma_chan++) {
local_chan = kzalloc(sizeof(struct pl08x_dma_chan),
GFP_KERNEL);
if (!local_chan) {
dev_err(&pd.dmac->dev,
"%s - no memory for channel\n", __func__);
return dmac.chancnt;
}
/*
* Save the DMAC channel number
* to indicate which registers to access
*/
local_chan->chan_id = dma_chan;
local_chan->chan.device = &dmac;
atomic_set(&local_chan->last_issued, 0);
local_chan->lc = atomic_read(&local_chan->last_issued);
if (pd.pd->reserved_for_slave)
local_chan->slave_only = pd.pd->reserved_for_slave(dma_chan);
else
dev_err(&pd.dmac->dev,
"%s - can't establish channels reserved for slaves\n",
__func__);
spin_lock_init(&local_chan->lock);
INIT_LIST_HEAD(&local_chan->desc_list);
INIT_LIST_HEAD(&local_chan->release_list);
list_add_tail(&local_chan->chan.device_node, &dmac.channels);
pd.chanwrap[dmac.chancnt++] = local_chan;
}
return dmac.chancnt;
}
| 为目前支持的多个channel进行必要的初始化,包括申请空间,设置初始值 |