Skip to content

Commit e472c64

Browse files
committed
Merge tag 'dmaengine-fix-5.4-rc6' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine fixes from Vinod Koul: "A few fixes to the dmaengine drivers: - fix in sprd driver for link list and potential memory leak - tegra transfer failure fix - imx size check fix for script_number - xilinx fix for 64bit AXIDMA and control reg update - qcom bam dma resource leak fix - cppi slave transfer fix when idle" * tag 'dmaengine-fix-5.4-rc6' of git://git.infradead.org/users/vkoul/slave-dma: dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle dmaengine: qcom: bam_dma: Fix resource leak dmaengine: sprd: Fix the possible memory leak issue dmaengine: xilinx_dma: Fix control reg update in vdma_channel_set_config dmaengine: xilinx_dma: Fix 64-bit simple AXIDMA transfer dmaengine: imx-sdma: fix size check for sdma script_number dmaengine: tegra210-adma: fix transfer failure dmaengine: sprd: Fix the link-list pointer register configuration issue
2 parents 320000e + bacdcb6 commit e472c64

File tree

7 files changed

+91
-4
lines changed

7 files changed

+91
-4
lines changed

drivers/dma/imx-sdma.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,6 +1707,14 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
17071707
if (!sdma->script_number)
17081708
sdma->script_number = SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1;
17091709

1710+
if (sdma->script_number > sizeof(struct sdma_script_start_addrs)
1711+
/ sizeof(s32)) {
1712+
dev_err(sdma->dev,
1713+
"SDMA script number %d not match with firmware.\n",
1714+
sdma->script_number);
1715+
return;
1716+
}
1717+
17101718
for (i = 0; i < sdma->script_number; i++)
17111719
if (addr_arr[i] > 0)
17121720
saddr_arr[i] = addr_arr[i];

drivers/dma/qcom/bam_dma.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,25 @@ static int bam_dma_terminate_all(struct dma_chan *chan)
694694

695695
/* remove all transactions, including active transaction */
696696
spin_lock_irqsave(&bchan->vc.lock, flag);
697+
/*
698+
* If we have transactions queued, then some might be committed to the
699+
* hardware in the desc fifo. The only way to reset the desc fifo is
700+
* to do a hardware reset (either by pipe or the entire block).
701+
* bam_chan_init_hw() will trigger a pipe reset, and also reinit the
702+
* pipe. If the pipe is left disabled (default state after pipe reset)
703+
* and is accessed by a connected hardware engine, a fatal error in
704+
* the BAM will occur. There is a small window where this could happen
705+
* with bam_chan_init_hw(), but it is assumed that the caller has
706+
* stopped activity on any attached hardware engine. Make sure to do
707+
* this first so that the BAM hardware doesn't cause memory corruption
708+
* by accessing freed resources.
709+
*/
710+
if (!list_empty(&bchan->desc_list)) {
711+
async_desc = list_first_entry(&bchan->desc_list,
712+
struct bam_async_desc, desc_node);
713+
bam_chan_init_hw(bchan, async_desc->dir);
714+
}
715+
697716
list_for_each_entry_safe(async_desc, tmp,
698717
&bchan->desc_list, desc_node) {
699718
list_add(&async_desc->vd.node, &bchan->vc.desc_issued);

drivers/dma/sprd-dma.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@
134134
#define SPRD_DMA_SRC_TRSF_STEP_OFFSET 0
135135
#define SPRD_DMA_TRSF_STEP_MASK GENMASK(15, 0)
136136

137+
/* SPRD DMA_SRC_BLK_STEP register definition */
138+
#define SPRD_DMA_LLIST_HIGH_MASK GENMASK(31, 28)
139+
#define SPRD_DMA_LLIST_HIGH_SHIFT 28
140+
137141
/* define DMA channel mode & trigger mode mask */
138142
#define SPRD_DMA_CHN_MODE_MASK GENMASK(7, 0)
139143
#define SPRD_DMA_TRG_MODE_MASK GENMASK(7, 0)
@@ -208,6 +212,7 @@ struct sprd_dma_dev {
208212
struct sprd_dma_chn channels[0];
209213
};
210214

215+
static void sprd_dma_free_desc(struct virt_dma_desc *vd);
211216
static bool sprd_dma_filter_fn(struct dma_chan *chan, void *param);
212217
static struct of_dma_filter_info sprd_dma_info = {
213218
.filter_fn = sprd_dma_filter_fn,
@@ -609,12 +614,19 @@ static int sprd_dma_alloc_chan_resources(struct dma_chan *chan)
609614
static void sprd_dma_free_chan_resources(struct dma_chan *chan)
610615
{
611616
struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
617+
struct virt_dma_desc *cur_vd = NULL;
612618
unsigned long flags;
613619

614620
spin_lock_irqsave(&schan->vc.lock, flags);
621+
if (schan->cur_desc)
622+
cur_vd = &schan->cur_desc->vd;
623+
615624
sprd_dma_stop(schan);
616625
spin_unlock_irqrestore(&schan->vc.lock, flags);
617626

627+
if (cur_vd)
628+
sprd_dma_free_desc(cur_vd);
629+
618630
vchan_free_chan_resources(&schan->vc);
619631
pm_runtime_put(chan->device->dev);
620632
}
@@ -717,6 +729,7 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,
717729
u32 int_mode = flags & SPRD_DMA_INT_MASK;
718730
int src_datawidth, dst_datawidth, src_step, dst_step;
719731
u32 temp, fix_mode = 0, fix_en = 0;
732+
phys_addr_t llist_ptr;
720733

721734
if (dir == DMA_MEM_TO_DEV) {
722735
src_step = sprd_dma_get_step(slave_cfg->src_addr_width);
@@ -814,13 +827,16 @@ static int sprd_dma_fill_desc(struct dma_chan *chan,
814827
* Set the link-list pointer point to next link-list
815828
* configuration's physical address.
816829
*/
817-
hw->llist_ptr = schan->linklist.phy_addr + temp;
830+
llist_ptr = schan->linklist.phy_addr + temp;
831+
hw->llist_ptr = lower_32_bits(llist_ptr);
832+
hw->src_blk_step = (upper_32_bits(llist_ptr) << SPRD_DMA_LLIST_HIGH_SHIFT) &
833+
SPRD_DMA_LLIST_HIGH_MASK;
818834
} else {
819835
hw->llist_ptr = 0;
836+
hw->src_blk_step = 0;
820837
}
821838

822839
hw->frg_step = 0;
823-
hw->src_blk_step = 0;
824840
hw->des_blk_step = 0;
825841
return 0;
826842
}
@@ -1023,15 +1039,22 @@ static int sprd_dma_resume(struct dma_chan *chan)
10231039
static int sprd_dma_terminate_all(struct dma_chan *chan)
10241040
{
10251041
struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
1042+
struct virt_dma_desc *cur_vd = NULL;
10261043
unsigned long flags;
10271044
LIST_HEAD(head);
10281045

10291046
spin_lock_irqsave(&schan->vc.lock, flags);
1047+
if (schan->cur_desc)
1048+
cur_vd = &schan->cur_desc->vd;
1049+
10301050
sprd_dma_stop(schan);
10311051

10321052
vchan_get_all_descriptors(&schan->vc, &head);
10331053
spin_unlock_irqrestore(&schan->vc.lock, flags);
10341054

1055+
if (cur_vd)
1056+
sprd_dma_free_desc(cur_vd);
1057+
10351058
vchan_dma_desc_free_list(&schan->vc, &head);
10361059
return 0;
10371060
}

drivers/dma/tegra210-adma.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#define ADMA_CH_CONFIG_MAX_BURST_SIZE 16
4141
#define ADMA_CH_CONFIG_WEIGHT_FOR_WRR(val) ((val) & 0xf)
4242
#define ADMA_CH_CONFIG_MAX_BUFS 8
43+
#define TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(reqs) (reqs << 4)
4344

4445
#define ADMA_CH_FIFO_CTRL 0x2c
4546
#define TEGRA210_ADMA_CH_FIFO_CTRL_TXSIZE(val) (((val) & 0xf) << 8)
@@ -77,6 +78,7 @@ struct tegra_adma;
7778
* @ch_req_tx_shift: Register offset for AHUB transmit channel select.
7879
* @ch_req_rx_shift: Register offset for AHUB receive channel select.
7980
* @ch_base_offset: Register offset of DMA channel registers.
81+
* @has_outstanding_reqs: If DMA channel can have outstanding requests.
8082
* @ch_fifo_ctrl: Default value for channel FIFO CTRL register.
8183
* @ch_req_mask: Mask for Tx or Rx channel select.
8284
* @ch_req_max: Maximum number of Tx or Rx channels available.
@@ -95,6 +97,7 @@ struct tegra_adma_chip_data {
9597
unsigned int ch_req_max;
9698
unsigned int ch_reg_size;
9799
unsigned int nr_channels;
100+
bool has_outstanding_reqs;
98101
};
99102

100103
/*
@@ -594,6 +597,8 @@ static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc,
594597
ADMA_CH_CTRL_FLOWCTRL_EN;
595598
ch_regs->config |= cdata->adma_get_burst_config(burst_size);
596599
ch_regs->config |= ADMA_CH_CONFIG_WEIGHT_FOR_WRR(1);
600+
if (cdata->has_outstanding_reqs)
601+
ch_regs->config |= TEGRA186_ADMA_CH_CONFIG_OUTSTANDING_REQS(8);
597602
ch_regs->fifo_ctrl = cdata->ch_fifo_ctrl;
598603
ch_regs->tc = desc->period_len & ADMA_CH_TC_COUNT_MASK;
599604

@@ -778,6 +783,7 @@ static const struct tegra_adma_chip_data tegra210_chip_data = {
778783
.ch_req_tx_shift = 28,
779784
.ch_req_rx_shift = 24,
780785
.ch_base_offset = 0,
786+
.has_outstanding_reqs = false,
781787
.ch_fifo_ctrl = TEGRA210_FIFO_CTRL_DEFAULT,
782788
.ch_req_mask = 0xf,
783789
.ch_req_max = 10,
@@ -792,6 +798,7 @@ static const struct tegra_adma_chip_data tegra186_chip_data = {
792798
.ch_req_tx_shift = 27,
793799
.ch_req_rx_shift = 22,
794800
.ch_base_offset = 0x10000,
801+
.has_outstanding_reqs = true,
795802
.ch_fifo_ctrl = TEGRA186_FIFO_CTRL_DEFAULT,
796803
.ch_req_mask = 0x1f,
797804
.ch_req_max = 20,

drivers/dma/ti/cppi41.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,9 +586,22 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg(
586586
enum dma_transfer_direction dir, unsigned long tx_flags, void *context)
587587
{
588588
struct cppi41_channel *c = to_cpp41_chan(chan);
589+
struct dma_async_tx_descriptor *txd = NULL;
590+
struct cppi41_dd *cdd = c->cdd;
589591
struct cppi41_desc *d;
590592
struct scatterlist *sg;
591593
unsigned int i;
594+
int error;
595+
596+
error = pm_runtime_get(cdd->ddev.dev);
597+
if (error < 0) {
598+
pm_runtime_put_noidle(cdd->ddev.dev);
599+
600+
return NULL;
601+
}
602+
603+
if (cdd->is_suspended)
604+
goto err_out_not_ready;
592605

593606
d = c->desc;
594607
for_each_sg(sgl, sg, sg_len, i) {
@@ -611,7 +624,13 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg(
611624
d++;
612625
}
613626

614-
return &c->txd;
627+
txd = &c->txd;
628+
629+
err_out_not_ready:
630+
pm_runtime_mark_last_busy(cdd->ddev.dev);
631+
pm_runtime_put_autosuspend(cdd->ddev.dev);
632+
633+
return txd;
615634
}
616635

617636
static void cppi41_compute_td_desc(struct cppi41_desc *d)

drivers/dma/xilinx/xilinx_dma.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@
6868
#define XILINX_DMA_DMACR_CIRC_EN BIT(1)
6969
#define XILINX_DMA_DMACR_RUNSTOP BIT(0)
7070
#define XILINX_DMA_DMACR_FSYNCSRC_MASK GENMASK(6, 5)
71+
#define XILINX_DMA_DMACR_DELAY_MASK GENMASK(31, 24)
72+
#define XILINX_DMA_DMACR_FRAME_COUNT_MASK GENMASK(23, 16)
73+
#define XILINX_DMA_DMACR_MASTER_MASK GENMASK(11, 8)
7174

7275
#define XILINX_DMA_REG_DMASR 0x0004
7376
#define XILINX_DMA_DMASR_EOL_LATE_ERR BIT(15)
@@ -1354,7 +1357,8 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
13541357
node);
13551358
hw = &segment->hw;
13561359

1357-
xilinx_write(chan, XILINX_DMA_REG_SRCDSTADDR, hw->buf_addr);
1360+
xilinx_write(chan, XILINX_DMA_REG_SRCDSTADDR,
1361+
xilinx_prep_dma_addr_t(hw->buf_addr));
13581362

13591363
/* Start the transfer */
13601364
dma_ctrl_write(chan, XILINX_DMA_REG_BTT,
@@ -2117,8 +2121,10 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
21172121
chan->config.gen_lock = cfg->gen_lock;
21182122
chan->config.master = cfg->master;
21192123

2124+
dmacr &= ~XILINX_DMA_DMACR_GENLOCK_EN;
21202125
if (cfg->gen_lock && chan->genlock) {
21212126
dmacr |= XILINX_DMA_DMACR_GENLOCK_EN;
2127+
dmacr &= ~XILINX_DMA_DMACR_MASTER_MASK;
21222128
dmacr |= cfg->master << XILINX_DMA_DMACR_MASTER_SHIFT;
21232129
}
21242130

@@ -2134,11 +2140,13 @@ int xilinx_vdma_channel_set_config(struct dma_chan *dchan,
21342140
chan->config.delay = cfg->delay;
21352141

21362142
if (cfg->coalesc <= XILINX_DMA_DMACR_FRAME_COUNT_MAX) {
2143+
dmacr &= ~XILINX_DMA_DMACR_FRAME_COUNT_MASK;
21372144
dmacr |= cfg->coalesc << XILINX_DMA_DMACR_FRAME_COUNT_SHIFT;
21382145
chan->config.coalesc = cfg->coalesc;
21392146
}
21402147

21412148
if (cfg->delay <= XILINX_DMA_DMACR_DELAY_MAX) {
2149+
dmacr &= ~XILINX_DMA_DMACR_DELAY_MASK;
21422150
dmacr |= cfg->delay << XILINX_DMA_DMACR_DELAY_SHIFT;
21432151
chan->config.delay = cfg->delay;
21442152
}

include/linux/platform_data/dma-imx-sdma.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ struct sdma_script_start_addrs {
5151
/* End of v2 array */
5252
s32 zcanfd_2_mcu_addr;
5353
s32 zqspi_2_mcu_addr;
54+
s32 mcu_2_ecspi_addr;
5455
/* End of v3 array */
56+
s32 mcu_2_zqspi_addr;
57+
/* End of v4 array */
5558
};
5659

5760
/**

0 commit comments

Comments
 (0)