aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2012-05-26 09:09:53 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-07-01 09:15:59 -0400
commit083be28a1056eaaebdf116126b9d859348160f45 (patch)
tree4f7e29394532a19d6f0cdde51aa16e1dde6c8ff2 /drivers/dma
parent01d8dc64e92a0abace41028db5b9ca298458543f (diff)
dmaengine: PL08x: use vchan's spinlock
Initialize the vchan struct, and use the provided spinlock rather than our own. Acked-by: Linus Walleij <linus.walleij@linaro.org> Tested-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/Kconfig1
-rw-r--r--drivers/dma/amba-pl08x.c45
2 files changed, 21 insertions, 25 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index eb2b60e8e1cb..be0dc3b7c409 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -53,6 +53,7 @@ config AMBA_PL08X
53 bool "ARM PrimeCell PL080 or PL081 support" 53 bool "ARM PrimeCell PL080 or PL081 support"
54 depends on ARM_AMBA && EXPERIMENTAL 54 depends on ARM_AMBA && EXPERIMENTAL
55 select DMA_ENGINE 55 select DMA_ENGINE
56 select DMA_VIRTUAL_CHANNELS
56 help 57 help
57 Platform has a PL08x DMAC device 58 Platform has a PL08x DMAC device
58 which can provide DMA engine support 59 which can provide DMA engine support
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 9a0642805b82..398a5da6f439 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -237,7 +237,6 @@ struct pl08x_dma_chan {
237 struct list_head issued_list; 237 struct list_head issued_list;
238 struct list_head done_list; 238 struct list_head done_list;
239 struct pl08x_txd *at; 239 struct pl08x_txd *at;
240 spinlock_t lock;
241 struct pl08x_driver_data *host; 240 struct pl08x_driver_data *host;
242 enum pl08x_dma_chan_state state; 241 enum pl08x_dma_chan_state state;
243 bool slave; 242 bool slave;
@@ -484,7 +483,7 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
484 unsigned long flags; 483 unsigned long flags;
485 size_t bytes = 0; 484 size_t bytes = 0;
486 485
487 spin_lock_irqsave(&plchan->lock, flags); 486 spin_lock_irqsave(&plchan->vc.lock, flags);
488 ch = plchan->phychan; 487 ch = plchan->phychan;
489 txd = plchan->at; 488 txd = plchan->at;
490 489
@@ -543,7 +542,7 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan *plchan)
543 } 542 }
544 } 543 }
545 544
546 spin_unlock_irqrestore(&plchan->lock, flags); 545 spin_unlock_irqrestore(&plchan->vc.lock, flags);
547 546
548 return bytes; 547 return bytes;
549} 548}
@@ -673,12 +672,12 @@ static void pl08x_phy_free(struct pl08x_dma_chan *plchan)
673 * Eww. We know this isn't going to deadlock 672 * Eww. We know this isn't going to deadlock
674 * but lockdep probably doesn't. 673 * but lockdep probably doesn't.
675 */ 674 */
676 spin_lock(&next->lock); 675 spin_lock(&next->vc.lock);
677 /* Re-check the state now that we have the lock */ 676 /* Re-check the state now that we have the lock */
678 success = next->state == PL08X_CHAN_WAITING; 677 success = next->state == PL08X_CHAN_WAITING;
679 if (success) 678 if (success)
680 pl08x_phy_reassign_start(plchan->phychan, next); 679 pl08x_phy_reassign_start(plchan->phychan, next);
681 spin_unlock(&next->lock); 680 spin_unlock(&next->vc.lock);
682 681
683 /* If the state changed, try to find another channel */ 682 /* If the state changed, try to find another channel */
684 if (!success) 683 if (!success)
@@ -1125,12 +1124,12 @@ static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
1125 unsigned long flags; 1124 unsigned long flags;
1126 dma_cookie_t cookie; 1125 dma_cookie_t cookie;
1127 1126
1128 spin_lock_irqsave(&plchan->lock, flags); 1127 spin_lock_irqsave(&plchan->vc.lock, flags);
1129 cookie = dma_cookie_assign(tx); 1128 cookie = dma_cookie_assign(tx);
1130 1129
1131 /* Put this onto the pending list */ 1130 /* Put this onto the pending list */
1132 list_add_tail(&txd->node, &plchan->pend_list); 1131 list_add_tail(&txd->node, &plchan->pend_list);
1133 spin_unlock_irqrestore(&plchan->lock, flags); 1132 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1134 1133
1135 return cookie; 1134 return cookie;
1136} 1135}
@@ -1318,13 +1317,13 @@ static void pl08x_issue_pending(struct dma_chan *chan)
1318 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan); 1317 struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
1319 unsigned long flags; 1318 unsigned long flags;
1320 1319
1321 spin_lock_irqsave(&plchan->lock, flags); 1320 spin_lock_irqsave(&plchan->vc.lock, flags);
1322 list_splice_tail_init(&plchan->pend_list, &plchan->issued_list); 1321 list_splice_tail_init(&plchan->pend_list, &plchan->issued_list);
1323 if (!list_empty(&plchan->issued_list)) { 1322 if (!list_empty(&plchan->issued_list)) {
1324 if (!plchan->phychan && plchan->state != PL08X_CHAN_WAITING) 1323 if (!plchan->phychan && plchan->state != PL08X_CHAN_WAITING)
1325 pl08x_phy_alloc_and_start(plchan); 1324 pl08x_phy_alloc_and_start(plchan);
1326 } 1325 }
1327 spin_unlock_irqrestore(&plchan->lock, flags); 1326 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1328} 1327}
1329 1328
1330static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan, 1329static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
@@ -1337,9 +1336,9 @@ static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
1337 if (!num_llis) { 1336 if (!num_llis) {
1338 unsigned long flags; 1337 unsigned long flags;
1339 1338
1340 spin_lock_irqsave(&plchan->lock, flags); 1339 spin_lock_irqsave(&plchan->vc.lock, flags);
1341 pl08x_free_txd(pl08x, txd); 1340 pl08x_free_txd(pl08x, txd);
1342 spin_unlock_irqrestore(&plchan->lock, flags); 1341 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1343 1342
1344 return -EINVAL; 1343 return -EINVAL;
1345 } 1344 }
@@ -1551,9 +1550,9 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1551 * Anything succeeds on channels with no physical allocation and 1550 * Anything succeeds on channels with no physical allocation and
1552 * no queued transfers. 1551 * no queued transfers.
1553 */ 1552 */
1554 spin_lock_irqsave(&plchan->lock, flags); 1553 spin_lock_irqsave(&plchan->vc.lock, flags);
1555 if (!plchan->phychan && !plchan->at) { 1554 if (!plchan->phychan && !plchan->at) {
1556 spin_unlock_irqrestore(&plchan->lock, flags); 1555 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1557 return 0; 1556 return 0;
1558 } 1557 }
1559 1558
@@ -1592,7 +1591,7 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1592 break; 1591 break;
1593 } 1592 }
1594 1593
1595 spin_unlock_irqrestore(&plchan->lock, flags); 1594 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1596 1595
1597 return ret; 1596 return ret;
1598} 1597}
@@ -1664,9 +1663,9 @@ static void pl08x_tasklet(unsigned long data)
1664 unsigned long flags; 1663 unsigned long flags;
1665 LIST_HEAD(head); 1664 LIST_HEAD(head);
1666 1665
1667 spin_lock_irqsave(&plchan->lock, flags); 1666 spin_lock_irqsave(&plchan->vc.lock, flags);
1668 list_splice_tail_init(&plchan->done_list, &head); 1667 list_splice_tail_init(&plchan->done_list, &head);
1669 spin_unlock_irqrestore(&plchan->lock, flags); 1668 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1670 1669
1671 while (!list_empty(&head)) { 1670 while (!list_empty(&head)) {
1672 struct pl08x_txd *txd = list_first_entry(&head, 1671 struct pl08x_txd *txd = list_first_entry(&head,
@@ -1681,9 +1680,9 @@ static void pl08x_tasklet(unsigned long data)
1681 pl08x_unmap_buffers(txd); 1680 pl08x_unmap_buffers(txd);
1682 1681
1683 /* Free the descriptor */ 1682 /* Free the descriptor */
1684 spin_lock_irqsave(&plchan->lock, flags); 1683 spin_lock_irqsave(&plchan->vc.lock, flags);
1685 pl08x_free_txd(pl08x, txd); 1684 pl08x_free_txd(pl08x, txd);
1686 spin_unlock_irqrestore(&plchan->lock, flags); 1685 spin_unlock_irqrestore(&plchan->vc.lock, flags);
1687 1686
1688 /* Callback to signal completion */ 1687 /* Callback to signal completion */
1689 if (callback) 1688 if (callback)
@@ -1724,7 +1723,7 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
1724 continue; 1723 continue;
1725 } 1724 }
1726 1725
1727 spin_lock(&plchan->lock); 1726 spin_lock(&plchan->vc.lock);
1728 tx = plchan->at; 1727 tx = plchan->at;
1729 if (tx) { 1728 if (tx) {
1730 plchan->at = NULL; 1729 plchan->at = NULL;
@@ -1745,7 +1744,7 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
1745 else 1744 else
1746 pl08x_phy_free(plchan); 1745 pl08x_phy_free(plchan);
1747 } 1746 }
1748 spin_unlock(&plchan->lock); 1747 spin_unlock(&plchan->vc.lock);
1749 1748
1750 /* Schedule tasklet on this channel */ 1749 /* Schedule tasklet on this channel */
1751 tasklet_schedule(&plchan->tasklet); 1750 tasklet_schedule(&plchan->tasklet);
@@ -1808,17 +1807,13 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
1808 "initialize virtual channel \"%s\"\n", 1807 "initialize virtual channel \"%s\"\n",
1809 chan->name); 1808 chan->name);
1810 1809
1811 chan->vc.chan.device = dmadev;
1812 dma_cookie_init(&chan->vc.chan);
1813
1814 spin_lock_init(&chan->lock);
1815 INIT_LIST_HEAD(&chan->pend_list); 1810 INIT_LIST_HEAD(&chan->pend_list);
1816 INIT_LIST_HEAD(&chan->issued_list); 1811 INIT_LIST_HEAD(&chan->issued_list);
1817 INIT_LIST_HEAD(&chan->done_list); 1812 INIT_LIST_HEAD(&chan->done_list);
1818 tasklet_init(&chan->tasklet, pl08x_tasklet, 1813 tasklet_init(&chan->tasklet, pl08x_tasklet,
1819 (unsigned long) chan); 1814 (unsigned long) chan);
1820 1815
1821 list_add_tail(&chan->vc.chan.device_node, &dmadev->channels); 1816 vchan_init(&chan->vc, dmadev);
1822 } 1817 }
1823 dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n", 1818 dev_info(&pl08x->adev->dev, "initialized %d virtual %s channels\n",
1824 i, slave ? "slave" : "memcpy"); 1819 i, slave ? "slave" : "memcpy");