Skip to content

Commit

Permalink
Merge branch 'fixes' of git://git.infradead.org/users/vkoul/slave-dma
Browse files Browse the repository at this point in the history
Pull dmaengine fixes from Vinod Koul:
 "Two fixes for slave dmaengine.  The first fixes cyclic dma transfers
  for pl330 and the second one makes us return the correct error code on
  probe"

* 'fixes' of git://git.infradead.org/users/vkoul/slave-dma:
  dma: pl330: Fix cyclic transfers
  pch_dma: fix error return code in pch_dma_probe()
  • Loading branch information
torvalds committed Aug 4, 2013
2 parents 3d90268 + fc51446 commit e56c756
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 26 deletions.
1 change: 1 addition & 0 deletions drivers/dma/pch_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,7 @@ static int pch_dma_probe(struct pci_dev *pdev,

if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
dev_err(&pdev->dev, "Cannot find proper base address\n");
err = -ENODEV;
goto err_disable_pdev;
}

Expand Down
93 changes: 67 additions & 26 deletions drivers/dma/pl330.c
Original file line number Diff line number Diff line change
Expand Up @@ -2505,6 +2505,10 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx)
/* Assign cookies to all nodes */
while (!list_empty(&last->node)) {
desc = list_entry(last->node.next, struct dma_pl330_desc, node);
if (pch->cyclic) {
desc->txd.callback = last->txd.callback;
desc->txd.callback_param = last->txd.callback_param;
}

dma_cookie_assign(&desc->txd);

Expand Down Expand Up @@ -2688,45 +2692,82 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
size_t period_len, enum dma_transfer_direction direction,
unsigned long flags, void *context)
{
struct dma_pl330_desc *desc;
struct dma_pl330_desc *desc = NULL, *first = NULL;
struct dma_pl330_chan *pch = to_pchan(chan);
struct dma_pl330_dmac *pdmac = pch->dmac;
unsigned int i;
dma_addr_t dst;
dma_addr_t src;

desc = pl330_get_desc(pch);
if (!desc) {
dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
__func__, __LINE__);
if (len % period_len != 0)
return NULL;
}

switch (direction) {
case DMA_MEM_TO_DEV:
desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 0;
desc->req.rqtype = MEMTODEV;
src = dma_addr;
dst = pch->fifo_addr;
break;
case DMA_DEV_TO_MEM:
desc->rqcfg.src_inc = 0;
desc->rqcfg.dst_inc = 1;
desc->req.rqtype = DEVTOMEM;
src = pch->fifo_addr;
dst = dma_addr;
break;
default:
if (!is_slave_direction(direction)) {
dev_err(pch->dmac->pif.dev, "%s:%d Invalid dma direction\n",
__func__, __LINE__);
return NULL;
}

desc->rqcfg.brst_size = pch->burst_sz;
desc->rqcfg.brst_len = 1;
for (i = 0; i < len / period_len; i++) {
desc = pl330_get_desc(pch);
if (!desc) {
dev_err(pch->dmac->pif.dev, "%s:%d Unable to fetch desc\n",
__func__, __LINE__);

pch->cyclic = true;
if (!first)
return NULL;

spin_lock_irqsave(&pdmac->pool_lock, flags);

while (!list_empty(&first->node)) {
desc = list_entry(first->node.next,
struct dma_pl330_desc, node);
list_move_tail(&desc->node, &pdmac->desc_pool);
}

list_move_tail(&first->node, &pdmac->desc_pool);

fill_px(&desc->px, dst, src, period_len);
spin_unlock_irqrestore(&pdmac->pool_lock, flags);

return NULL;
}

switch (direction) {
case DMA_MEM_TO_DEV:
desc->rqcfg.src_inc = 1;
desc->rqcfg.dst_inc = 0;
desc->req.rqtype = MEMTODEV;
src = dma_addr;
dst = pch->fifo_addr;
break;
case DMA_DEV_TO_MEM:
desc->rqcfg.src_inc = 0;
desc->rqcfg.dst_inc = 1;
desc->req.rqtype = DEVTOMEM;
src = pch->fifo_addr;
dst = dma_addr;
break;
default:
break;
}

desc->rqcfg.brst_size = pch->burst_sz;
desc->rqcfg.brst_len = 1;
fill_px(&desc->px, dst, src, period_len);

if (!first)
first = desc;
else
list_add_tail(&desc->node, &first->node);

dma_addr += period_len;
}

if (!desc)
return NULL;

pch->cyclic = true;
desc->txd.flags = flags;

return &desc->txd;
}
Expand Down

0 comments on commit e56c756

Please sign in to comment.