.. | .. |
---|
212 | 212 | int irq; |
---|
213 | 213 | struct clk *clk; |
---|
214 | 214 | u32 save_gim; |
---|
| 215 | + u32 save_gs; |
---|
215 | 216 | struct dma_pool *at_xdmac_desc_pool; |
---|
216 | 217 | struct at_xdmac_chan chan[]; |
---|
217 | 218 | }; |
---|
.. | .. |
---|
677 | 678 | if (!desc) { |
---|
678 | 679 | dev_err(chan2dev(chan), "can't get descriptor\n"); |
---|
679 | 680 | if (first) |
---|
680 | | - list_splice_init(&first->descs_list, &atchan->free_descs_list); |
---|
| 681 | + list_splice_tail_init(&first->descs_list, |
---|
| 682 | + &atchan->free_descs_list); |
---|
681 | 683 | goto spin_unlock; |
---|
682 | 684 | } |
---|
683 | 685 | |
---|
.. | .. |
---|
765 | 767 | if (!desc) { |
---|
766 | 768 | dev_err(chan2dev(chan), "can't get descriptor\n"); |
---|
767 | 769 | if (first) |
---|
768 | | - list_splice_init(&first->descs_list, &atchan->free_descs_list); |
---|
| 770 | + list_splice_tail_init(&first->descs_list, |
---|
| 771 | + &atchan->free_descs_list); |
---|
769 | 772 | spin_unlock_irqrestore(&atchan->lock, irqflags); |
---|
770 | 773 | return NULL; |
---|
771 | 774 | } |
---|
.. | .. |
---|
967 | 970 | NULL, |
---|
968 | 971 | src_addr, dst_addr, |
---|
969 | 972 | xt, xt->sgl); |
---|
| 973 | + if (!first) |
---|
| 974 | + return NULL; |
---|
970 | 975 | |
---|
971 | 976 | /* Length of the block is (BLEN+1) microblocks. */ |
---|
972 | 977 | for (i = 0; i < xt->numf - 1; i++) |
---|
.. | .. |
---|
997 | 1002 | src_addr, dst_addr, |
---|
998 | 1003 | xt, chunk); |
---|
999 | 1004 | if (!desc) { |
---|
1000 | | - list_splice_init(&first->descs_list, |
---|
1001 | | - &atchan->free_descs_list); |
---|
| 1005 | + if (first) |
---|
| 1006 | + list_splice_tail_init(&first->descs_list, |
---|
| 1007 | + &atchan->free_descs_list); |
---|
1002 | 1008 | return NULL; |
---|
1003 | 1009 | } |
---|
1004 | 1010 | |
---|
.. | .. |
---|
1076 | 1082 | if (!desc) { |
---|
1077 | 1083 | dev_err(chan2dev(chan), "can't get descriptor\n"); |
---|
1078 | 1084 | if (first) |
---|
1079 | | - list_splice_init(&first->descs_list, &atchan->free_descs_list); |
---|
| 1085 | + list_splice_tail_init(&first->descs_list, |
---|
| 1086 | + &atchan->free_descs_list); |
---|
1080 | 1087 | return NULL; |
---|
1081 | 1088 | } |
---|
1082 | 1089 | |
---|
.. | .. |
---|
1250 | 1257 | sg_dma_len(sg), |
---|
1251 | 1258 | value); |
---|
1252 | 1259 | if (!desc && first) |
---|
1253 | | - list_splice_init(&first->descs_list, |
---|
1254 | | - &atchan->free_descs_list); |
---|
| 1260 | + list_splice_tail_init(&first->descs_list, |
---|
| 1261 | + &atchan->free_descs_list); |
---|
1255 | 1262 | |
---|
1256 | 1263 | if (!first) |
---|
1257 | 1264 | first = desc; |
---|
.. | .. |
---|
1526 | 1533 | return ret; |
---|
1527 | 1534 | } |
---|
1528 | 1535 | |
---|
1529 | | -/* Call must be protected by lock. */ |
---|
1530 | | -static void at_xdmac_remove_xfer(struct at_xdmac_chan *atchan, |
---|
1531 | | - struct at_xdmac_desc *desc) |
---|
1532 | | -{ |
---|
1533 | | - dev_dbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, desc); |
---|
1534 | | - |
---|
1535 | | - /* |
---|
1536 | | - * Remove the transfer from the transfer list then move the transfer |
---|
1537 | | - * descriptors into the free descriptors list. |
---|
1538 | | - */ |
---|
1539 | | - list_del(&desc->xfer_node); |
---|
1540 | | - list_splice_init(&desc->descs_list, &atchan->free_descs_list); |
---|
1541 | | -} |
---|
1542 | | - |
---|
1543 | 1536 | static void at_xdmac_advance_work(struct at_xdmac_chan *atchan) |
---|
1544 | 1537 | { |
---|
1545 | 1538 | struct at_xdmac_desc *desc; |
---|
.. | .. |
---|
1650 | 1643 | } |
---|
1651 | 1644 | |
---|
1652 | 1645 | txd = &desc->tx_dma_desc; |
---|
1653 | | - |
---|
1654 | | - at_xdmac_remove_xfer(atchan, desc); |
---|
| 1646 | + dma_cookie_complete(txd); |
---|
| 1647 | + /* Remove the transfer from the transfer list. */ |
---|
| 1648 | + list_del(&desc->xfer_node); |
---|
1655 | 1649 | spin_unlock_irq(&atchan->lock); |
---|
1656 | 1650 | |
---|
1657 | | - dma_cookie_complete(txd); |
---|
1658 | 1651 | if (txd->flags & DMA_PREP_INTERRUPT) |
---|
1659 | 1652 | dmaengine_desc_get_callback_invoke(txd, NULL); |
---|
1660 | 1653 | |
---|
1661 | 1654 | dma_run_dependencies(txd); |
---|
1662 | 1655 | |
---|
1663 | 1656 | spin_lock_irq(&atchan->lock); |
---|
| 1657 | + /* Move the xfer descriptors into the free descriptors list. */ |
---|
| 1658 | + list_splice_tail_init(&desc->descs_list, |
---|
| 1659 | + &atchan->free_descs_list); |
---|
1664 | 1660 | at_xdmac_advance_work(atchan); |
---|
1665 | 1661 | spin_unlock_irq(&atchan->lock); |
---|
1666 | 1662 | } |
---|
.. | .. |
---|
1807 | 1803 | cpu_relax(); |
---|
1808 | 1804 | |
---|
1809 | 1805 | /* Cancel all pending transfers. */ |
---|
1810 | | - list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node) |
---|
1811 | | - at_xdmac_remove_xfer(atchan, desc); |
---|
| 1806 | + list_for_each_entry_safe(desc, _desc, &atchan->xfers_list, xfer_node) { |
---|
| 1807 | + list_del(&desc->xfer_node); |
---|
| 1808 | + list_splice_tail_init(&desc->descs_list, |
---|
| 1809 | + &atchan->free_descs_list); |
---|
| 1810 | + } |
---|
1812 | 1811 | |
---|
1813 | 1812 | clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); |
---|
1814 | 1813 | clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); |
---|
.. | .. |
---|
1910 | 1909 | } |
---|
1911 | 1910 | } |
---|
1912 | 1911 | atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM); |
---|
| 1912 | + atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS); |
---|
1913 | 1913 | |
---|
1914 | 1914 | at_xdmac_off(atxdmac); |
---|
1915 | 1915 | clk_disable_unprepare(atxdmac->clk); |
---|
.. | .. |
---|
1946 | 1946 | at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc); |
---|
1947 | 1947 | at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim); |
---|
1948 | 1948 | wmb(); |
---|
1949 | | - at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); |
---|
| 1949 | + if (atxdmac->save_gs & atchan->mask) |
---|
| 1950 | + at_xdmac_write(atxdmac, AT_XDMAC_GE, atchan->mask); |
---|
1950 | 1951 | } |
---|
1951 | 1952 | } |
---|
1952 | 1953 | return 0; |
---|