hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/dma/at_xdmac.c
....@@ -212,6 +212,7 @@
212212 int irq;
213213 struct clk *clk;
214214 u32 save_gim;
215
+ u32 save_gs;
215216 struct dma_pool *at_xdmac_desc_pool;
216217 struct at_xdmac_chan chan[];
217218 };
....@@ -677,7 +678,8 @@
677678 if (!desc) {
678679 dev_err(chan2dev(chan), "can't get descriptor\n");
679680 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);
681683 goto spin_unlock;
682684 }
683685
....@@ -765,7 +767,8 @@
765767 if (!desc) {
766768 dev_err(chan2dev(chan), "can't get descriptor\n");
767769 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);
769772 spin_unlock_irqrestore(&atchan->lock, irqflags);
770773 return NULL;
771774 }
....@@ -967,6 +970,8 @@
967970 NULL,
968971 src_addr, dst_addr,
969972 xt, xt->sgl);
973
+ if (!first)
974
+ return NULL;
970975
971976 /* Length of the block is (BLEN+1) microblocks. */
972977 for (i = 0; i < xt->numf - 1; i++)
....@@ -997,8 +1002,9 @@
9971002 src_addr, dst_addr,
9981003 xt, chunk);
9991004 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);
10021008 return NULL;
10031009 }
10041010
....@@ -1076,7 +1082,8 @@
10761082 if (!desc) {
10771083 dev_err(chan2dev(chan), "can't get descriptor\n");
10781084 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);
10801087 return NULL;
10811088 }
10821089
....@@ -1250,8 +1257,8 @@
12501257 sg_dma_len(sg),
12511258 value);
12521259 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);
12551262
12561263 if (!first)
12571264 first = desc;
....@@ -1526,20 +1533,6 @@
15261533 return ret;
15271534 }
15281535
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
-
15431536 static void at_xdmac_advance_work(struct at_xdmac_chan *atchan)
15441537 {
15451538 struct at_xdmac_desc *desc;
....@@ -1650,17 +1643,20 @@
16501643 }
16511644
16521645 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);
16551649 spin_unlock_irq(&atchan->lock);
16561650
1657
- dma_cookie_complete(txd);
16581651 if (txd->flags & DMA_PREP_INTERRUPT)
16591652 dmaengine_desc_get_callback_invoke(txd, NULL);
16601653
16611654 dma_run_dependencies(txd);
16621655
16631656 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);
16641660 at_xdmac_advance_work(atchan);
16651661 spin_unlock_irq(&atchan->lock);
16661662 }
....@@ -1807,8 +1803,11 @@
18071803 cpu_relax();
18081804
18091805 /* 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
+ }
18121811
18131812 clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
18141813 clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status);
....@@ -1910,6 +1909,7 @@
19101909 }
19111910 }
19121911 atxdmac->save_gim = at_xdmac_read(atxdmac, AT_XDMAC_GIM);
1912
+ atxdmac->save_gs = at_xdmac_read(atxdmac, AT_XDMAC_GS);
19131913
19141914 at_xdmac_off(atxdmac);
19151915 clk_disable_unprepare(atxdmac->clk);
....@@ -1946,7 +1946,8 @@
19461946 at_xdmac_chan_write(atchan, AT_XDMAC_CNDC, atchan->save_cndc);
19471947 at_xdmac_chan_write(atchan, AT_XDMAC_CIE, atchan->save_cim);
19481948 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);
19501951 }
19511952 }
19521953 return 0;