Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dmaengine: qcom: bam_dma: use lock guards

Simplify locking across the driver with lock guards from cleanup.h.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Link: https://patch.msgid.link/20251106-qcom-bam-dma-refactor-v1-2-0e2baaf3d81a@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Bartosz Golaszewski and committed by
Vinod Koul
20f58183 892f2bb4

+55 -69
+55 -69
drivers/dma/qcom/bam_dma.c
··· 24 24 */ 25 25 26 26 #include <linux/circ_buf.h> 27 + #include <linux/cleanup.h> 27 28 #include <linux/clk.h> 28 29 #include <linux/device.h> 29 30 #include <linux/dma-mapping.h> ··· 571 570 struct bam_chan *bchan = to_bam_chan(chan); 572 571 struct bam_device *bdev = bchan->bdev; 573 572 u32 val; 574 - unsigned long flags; 575 573 int ret; 576 574 577 575 ret = pm_runtime_get_sync(bdev->dev); ··· 584 584 goto err; 585 585 } 586 586 587 - spin_lock_irqsave(&bchan->vc.lock, flags); 588 - bam_reset_channel(bchan); 589 - spin_unlock_irqrestore(&bchan->vc.lock, flags); 587 + scoped_guard(spinlock_irqsave, &bchan->vc.lock) 588 + bam_reset_channel(bchan); 590 589 591 590 dma_free_wc(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt, 592 591 bchan->fifo_phys); ··· 623 624 struct dma_slave_config *cfg) 624 625 { 625 626 struct bam_chan *bchan = to_bam_chan(chan); 626 - unsigned long flag; 627 627 628 - spin_lock_irqsave(&bchan->vc.lock, flag); 628 + guard(spinlock_irqsave)(&bchan->vc.lock); 629 + 629 630 memcpy(&bchan->slave, cfg, sizeof(*cfg)); 630 631 bchan->reconfigure = 1; 631 - spin_unlock_irqrestore(&bchan->vc.lock, flag); 632 632 633 633 return 0; 634 634 } ··· 724 726 { 725 727 struct bam_chan *bchan = to_bam_chan(chan); 726 728 struct bam_async_desc *async_desc, *tmp; 727 - unsigned long flag; 728 729 LIST_HEAD(head); 729 730 730 731 /* remove all transactions, including active transaction */ 731 - spin_lock_irqsave(&bchan->vc.lock, flag); 732 - /* 733 - * If we have transactions queued, then some might be committed to the 734 - * hardware in the desc fifo. The only way to reset the desc fifo is 735 - * to do a hardware reset (either by pipe or the entire block). 736 - * bam_chan_init_hw() will trigger a pipe reset, and also reinit the 737 - * pipe. If the pipe is left disabled (default state after pipe reset) 738 - * and is accessed by a connected hardware engine, a fatal error in 739 - * the BAM will occur. There is a small window where this could happen 740 - * with bam_chan_init_hw(), but it is assumed that the caller has 741 - * stopped activity on any attached hardware engine. Make sure to do 742 - * this first so that the BAM hardware doesn't cause memory corruption 743 - * by accessing freed resources. 744 - */ 745 - if (!list_empty(&bchan->desc_list)) { 746 - async_desc = list_first_entry(&bchan->desc_list, 747 - struct bam_async_desc, desc_node); 748 - bam_chan_init_hw(bchan, async_desc->dir); 749 - } 732 + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { 733 + /* 734 + * If we have transactions queued, then some might be committed to the 735 + * hardware in the desc fifo. The only way to reset the desc fifo is 736 + * to do a hardware reset (either by pipe or the entire block). 737 + * bam_chan_init_hw() will trigger a pipe reset, and also reinit the 738 + * pipe. If the pipe is left disabled (default state after pipe reset) 739 + * and is accessed by a connected hardware engine, a fatal error in 740 + * the BAM will occur. There is a small window where this could happen 741 + * with bam_chan_init_hw(), but it is assumed that the caller has 742 + * stopped activity on any attached hardware engine. Make sure to do 743 + * this first so that the BAM hardware doesn't cause memory corruption 744 + * by accessing freed resources. 745 + */ 746 + if (!list_empty(&bchan->desc_list)) { 747 + async_desc = list_first_entry(&bchan->desc_list, 748 + struct bam_async_desc, desc_node); 749 + bam_chan_init_hw(bchan, async_desc->dir); 750 + } 750 751 751 - list_for_each_entry_safe(async_desc, tmp, 752 - &bchan->desc_list, desc_node) { 753 - list_add(&async_desc->vd.node, &bchan->vc.desc_issued); 754 - list_del(&async_desc->desc_node); 755 - } 752 + list_for_each_entry_safe(async_desc, tmp, 753 + &bchan->desc_list, desc_node) { 754 + list_add(&async_desc->vd.node, &bchan->vc.desc_issued); 755 + list_del(&async_desc->desc_node); 756 + } 756 757 757 - vchan_get_all_descriptors(&bchan->vc, &head); 758 - spin_unlock_irqrestore(&bchan->vc.lock, flag); 758 + vchan_get_all_descriptors(&bchan->vc, &head); 759 + } 759 760 760 761 vchan_dma_desc_free_list(&bchan->vc, &head); 761 762 ··· 770 773 { 771 774 struct bam_chan *bchan = to_bam_chan(chan); 772 775 struct bam_device *bdev = bchan->bdev; 773 - unsigned long flag; 774 776 int ret; 775 777 776 778 ret = pm_runtime_get_sync(bdev->dev); 777 779 if (ret < 0) 778 780 return ret; 779 781 780 - spin_lock_irqsave(&bchan->vc.lock, flag); 781 - writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); 782 - bchan->paused = 1; 783 - spin_unlock_irqrestore(&bchan->vc.lock, flag); 782 + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { 783 + writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); 784 + bchan->paused = 1; 785 + } 784 786 pm_runtime_mark_last_busy(bdev->dev); 785 787 pm_runtime_put_autosuspend(bdev->dev); 786 788 ··· 795 799 { 796 800 struct bam_chan *bchan = to_bam_chan(chan); 797 801 struct bam_device *bdev = bchan->bdev; 798 - unsigned long flag; 799 802 int ret; 800 803 801 804 ret = pm_runtime_get_sync(bdev->dev); 802 805 if (ret < 0) 803 806 return ret; 804 807 805 - spin_lock_irqsave(&bchan->vc.lock, flag); 806 - writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); 807 - bchan->paused = 0; 808 - spin_unlock_irqrestore(&bchan->vc.lock, flag); 808 + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { 809 + writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); 810 + bchan->paused = 0; 811 + } 809 812 pm_runtime_mark_last_busy(bdev->dev); 810 813 pm_runtime_put_autosuspend(bdev->dev); 811 814 ··· 821 826 static u32 process_channel_irqs(struct bam_device *bdev) 822 827 { 823 828 u32 i, srcs, pipe_stts, offset, avail; 824 - unsigned long flags; 825 829 struct bam_async_desc *async_desc, *tmp; 826 830 827 831 srcs = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_EE)); ··· 840 846 841 847 writel_relaxed(pipe_stts, bam_addr(bdev, i, BAM_P_IRQ_CLR)); 842 848 843 - spin_lock_irqsave(&bchan->vc.lock, flags); 849 + guard(spinlock_irqsave)(&bchan->vc.lock); 844 850 845 851 offset = readl_relaxed(bam_addr(bdev, i, BAM_P_SW_OFSTS)) & 846 852 P_SW_OFSTS_MASK; ··· 879 885 } 880 886 list_del(&async_desc->desc_node); 881 887 } 882 - 883 - spin_unlock_irqrestore(&bchan->vc.lock, flags); 884 888 } 885 889 886 890 return srcs; ··· 942 950 int ret; 943 951 size_t residue = 0; 944 952 unsigned int i; 945 - unsigned long flags; 946 953 947 954 ret = dma_cookie_status(chan, cookie, txstate); 948 955 if (ret == DMA_COMPLETE) ··· 950 959 if (!txstate) 951 960 return bchan->paused ? DMA_PAUSED : ret; 952 961 953 - spin_lock_irqsave(&bchan->vc.lock, flags); 954 - vd = vchan_find_desc(&bchan->vc, cookie); 955 - if (vd) { 956 - residue = container_of(vd, struct bam_async_desc, vd)->length; 957 - } else { 958 - list_for_each_entry(async_desc, &bchan->desc_list, desc_node) { 959 - if (async_desc->vd.tx.cookie != cookie) 960 - continue; 962 + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { 963 + vd = vchan_find_desc(&bchan->vc, cookie); 964 + if (vd) { 965 + residue = container_of(vd, struct bam_async_desc, vd)->length; 966 + } else { 967 + list_for_each_entry(async_desc, &bchan->desc_list, desc_node) { 968 + if (async_desc->vd.tx.cookie != cookie) 969 + continue; 961 970 962 - for (i = 0; i < async_desc->num_desc; i++) 963 - residue += le16_to_cpu( 964 - async_desc->curr_desc[i].size); 971 + for (i = 0; i < async_desc->num_desc; i++) 972 + residue += le16_to_cpu( 973 + async_desc->curr_desc[i].size); 974 + } 965 975 } 966 976 } 967 - 968 - spin_unlock_irqrestore(&bchan->vc.lock, flags); 969 977 970 978 dma_set_residue(txstate, residue); 971 979 ··· 1106 1116 { 1107 1117 struct bam_device *bdev = from_tasklet(bdev, t, task); 1108 1118 struct bam_chan *bchan; 1109 - unsigned long flags; 1110 1119 unsigned int i; 1111 1120 1112 1121 /* go through the channels and kick off transactions */ 1113 1122 for (i = 0; i < bdev->num_channels; i++) { 1114 1123 bchan = &bdev->channels[i]; 1115 - spin_lock_irqsave(&bchan->vc.lock, flags); 1124 + 1125 + guard(spinlock_irqsave)(&bchan->vc.lock); 1116 1126 1117 1127 if (!list_empty(&bchan->vc.desc_issued) && !IS_BUSY(bchan)) 1118 1128 bam_start_dma(bchan); 1119 - spin_unlock_irqrestore(&bchan->vc.lock, flags); 1120 1129 } 1121 1130 1122 1131 } ··· 1129 1140 static void bam_issue_pending(struct dma_chan *chan) 1130 1141 { 1131 1142 struct bam_chan *bchan = to_bam_chan(chan); 1132 - unsigned long flags; 1133 1143 1134 - spin_lock_irqsave(&bchan->vc.lock, flags); 1144 + guard(spinlock_irqsave)(&bchan->vc.lock); 1135 1145 1136 1146 /* if work pending and idle, start a transaction */ 1137 1147 if (vchan_issue_pending(&bchan->vc) && !IS_BUSY(bchan)) 1138 1148 bam_start_dma(bchan); 1139 - 1140 - spin_unlock_irqrestore(&bchan->vc.lock, flags); 1141 1149 } 1142 1150 1143 1151 /**