/*
* Might take too long to do all at once
* if so - free some then hand it off
*/
void pl08x_memrelease(void)
{
struct pl08x_txd *local_txd, *next;
unsigned long flags;
int chan;
for (chan = 0; chan < MAX_DMA_CHANNELS; chan++) {
list_for_each_entry_safe(local_txd, next, &pd.chanwrap[chan]->release_list, txd_list)
{
spin_lock_irqsave(&pd.lock, flags);
if (!local_txd)
dev_err(&pd.dmac->dev,
"%s - no descriptor\n", __func__);
if (local_txd->tx.callback) {
((struct pl08x_callback_param *)
local_txd->tx.callback_param)->act =
PL08X_RELEASE;
local_txd->tx.callback(
local_txd->tx.callback_param);
}
list_del(&local_txd->txd_list);
dma_pool_free(pd.pool, local_txd->llis_va,
local_txd->llis_bus);
/*
* p/m data not mapped - uses coherent or io mem
*/
if (!local_txd->slave) {
dma_unmap_single(dmac.dev,
local_txd->srcbus.addr, local_txd->len,
local_txd->srcdir);
dma_unmap_single(dmac.dev,
local_txd->dstbus.addr, local_txd->len,
local_txd->dstdir);
}
kfree(local_txd);
spin_unlock_irqrestore(&pd.lock, flags);
}
}
pd.pool_ctr = 0;
}
| 释放DMA内存 |