diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-05-26 09:09:53 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2012-07-01 09:15:59 -0400 |
commit | 083be28a1056eaaebdf116126b9d859348160f45 (patch) | |
tree | 4f7e29394532a19d6f0cdde51aa16e1dde6c8ff2 /drivers/dma | |
parent | 01d8dc64e92a0abace41028db5b9ca298458543f (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/Kconfig | 1 | ||||
-rw-r--r-- | drivers/dma/amba-pl08x.c | 45 |
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 | ||
1330 | static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan, | 1329 | static 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"); |