diff options
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r-- | drivers/dma/amba-pl08x.c | 11 |
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); |