| .. | .. |
|---|
| 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; |
|---|