aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma/amba-pl08x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r--drivers/dma/amba-pl08x.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 650e2bbc7aa..bf6f7d02c9f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -959,6 +959,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
959 ch->signal, 959 ch->signal,
960 plchan->name); 960 plchan->name);
961 961
962 plchan->phychan_hold++;
962 plchan->phychan = ch; 963 plchan->phychan = ch;
963 964
964 return 0; 965 return 0;
@@ -998,6 +999,8 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
998 /* Do this memcpy whenever there is a channel ready */ 999 /* Do this memcpy whenever there is a channel ready */
999 plchan->state = PL08X_CHAN_WAITING; 1000 plchan->state = PL08X_CHAN_WAITING;
1000 plchan->waiting = txd; 1001 plchan->waiting = txd;
1002 } else {
1003 plchan->phychan_hold--;
1001 } 1004 }
1002 1005
1003 /* This unlock follows the lock in the prep() function */ 1006 /* This unlock follows the lock in the prep() function */
@@ -1585,6 +1588,7 @@ static void pl08x_tasklet(unsigned long data)
1585 */ 1588 */
1586 plchan->lc = txd->tx.cookie; 1589 plchan->lc = txd->tx.cookie;
1587 } 1590 }
1591
1588 /* 1592 /*
1589 * If a new descriptor is queued, set it up 1593 * If a new descriptor is queued, set it up
1590 * plchan->at is NULL here 1594 * plchan->at is NULL here
@@ -1598,6 +1602,12 @@ static void pl08x_tasklet(unsigned long data)
1598 list_del(&next->node); 1602 list_del(&next->node);
1599 1603
1600 pl08x_start_txd(plchan, next); 1604 pl08x_start_txd(plchan, next);
1605 } else if (plchan->phychan_hold) {
1606 /*
1607 * This channel is still in use - we have a new txd being
1608 * prepared and will soon be queued. Don't give up the
1609 * physical channel.
1610 */
1601 } else { 1611 } else {
1602 struct pl08x_dma_chan *waiting = NULL; 1612 struct pl08x_dma_chan *waiting = NULL;
1603 1613
@@ -1625,6 +1635,7 @@ static void pl08x_tasklet(unsigned long data)
1625 ret = prep_phy_channel(waiting, 1635 ret = prep_phy_channel(waiting,
1626 waiting->waiting); 1636 waiting->waiting);
1627 BUG_ON(ret); 1637 BUG_ON(ret);
1638 waiting->phychan_hold--;
1628 waiting->state = PL08X_CHAN_RUNNING; 1639 waiting->state = PL08X_CHAN_RUNNING;
1629 waiting->waiting = NULL; 1640 waiting->waiting = NULL;
1630 pl08x_issue_pending(&waiting->chan); 1641 pl08x_issue_pending(&waiting->chan);