summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml4
-rw-r--r--drivers/dma/altera-msgdma.c4
-rw-r--r--drivers/dma/idxd/device.c9
-rw-r--r--drivers/dma/imx-sdma.c18
-rw-r--r--drivers/dma/ioat/init.c2
-rw-r--r--drivers/dma/ptdma/ptdma-dmaengine.c24
-rw-r--r--drivers/dma/stm32-dma.c1
7 files changed, 46 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
index 7a4f415d74dc..1e25c5b0fb4d 100644
--- a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
+++ b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/dma/renesas,rz-dmac.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: Renesas RZ/G2L DMA Controller
+title: Renesas RZ/{G2L,G2UL,V2L} DMA Controller
maintainers:
- Biju Das <biju.das.jz@bp.renesas.com>
@@ -16,7 +16,9 @@ properties:
compatible:
items:
- enum:
+ - renesas,r9a07g043-dmac # RZ/G2UL
- renesas,r9a07g044-dmac # RZ/G2{L,LC}
+ - renesas,r9a07g054-dmac # RZ/V2L
- const: renesas,rz-dmac
reg:
diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c
index f5b885d69cd3..6f56dfd375e3 100644
--- a/drivers/dma/altera-msgdma.c
+++ b/drivers/dma/altera-msgdma.c
@@ -891,9 +891,7 @@ static int msgdma_probe(struct platform_device *pdev)
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (ret) {
dev_warn(&pdev->dev, "unable to set coherent mask to 64");
- ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (ret)
- goto fail;
+ goto fail;
}
msgdma_reset(mdev);
diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
index 573ad8b86804..3061fe857d69 100644
--- a/drivers/dma/idxd/device.c
+++ b/drivers/dma/idxd/device.c
@@ -681,8 +681,13 @@ static void idxd_groups_clear_state(struct idxd_device *idxd)
group->use_rdbuf_limit = false;
group->rdbufs_allowed = 0;
group->rdbufs_reserved = 0;
- group->tc_a = -1;
- group->tc_b = -1;
+ if (idxd->hw.version < DEVICE_VERSION_2 && !tc_override) {
+ group->tc_a = 1;
+ group->tc_b = 1;
+ } else {
+ group->tc_a = -1;
+ group->tc_b = -1;
+ }
}
}
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 75ec0754d4ad..8cc5103193c3 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -701,6 +701,11 @@ static int sdma_config_ownership(struct sdma_channel *sdmac,
return 0;
}
+static int is_sdma_channel_enabled(struct sdma_engine *sdma, int channel)
+{
+ return !!(readl(sdma->regs + SDMA_H_STATSTOP) & BIT(channel));
+}
+
static void sdma_enable_channel(struct sdma_engine *sdma, int channel)
{
writel(BIT(channel), sdma->regs + SDMA_H_START);
@@ -842,7 +847,6 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
*/
desc->chn_real_count = bd->mode.count;
- bd->mode.status |= BD_DONE;
bd->mode.count = desc->period_len;
desc->buf_ptail = desc->buf_tail;
desc->buf_tail = (desc->buf_tail + 1) % desc->num_bd;
@@ -857,9 +861,21 @@ static void sdma_update_channel_loop(struct sdma_channel *sdmac)
dmaengine_desc_get_callback_invoke(&desc->vd.tx, NULL);
spin_lock(&sdmac->vc.lock);
+ /* Assign buffer ownership to SDMA */
+ bd->mode.status |= BD_DONE;
+
if (error)
sdmac->status = old_status;
}
+
+ /*
+ * SDMA stops cyclic channel when DMA request triggers a channel and no SDMA
+ * owned buffer is available (i.e. BD_DONE was set too late).
+ */
+ if (!is_sdma_channel_enabled(sdmac->sdma, sdmac->channel)) {
+ dev_warn(sdmac->sdma->dev, "restart cyclic channel %d\n", sdmac->channel);
+ sdma_enable_channel(sdmac->sdma, sdmac->channel);
+ }
}
static void mxc_sdma_handle_channel_normal(struct sdma_channel *data)
diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c
index 373b8dac6c9b..5d707ff63554 100644
--- a/drivers/dma/ioat/init.c
+++ b/drivers/dma/ioat/init.c
@@ -1365,8 +1365,6 @@ static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (err)
- err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (err)
return err;
device = alloc_ioatdma(pdev, iomap[IOAT_MMIO_BAR]);
diff --git a/drivers/dma/ptdma/ptdma-dmaengine.c b/drivers/dma/ptdma/ptdma-dmaengine.c
index c9e52f6f2f50..91b93e8d9779 100644
--- a/drivers/dma/ptdma/ptdma-dmaengine.c
+++ b/drivers/dma/ptdma/ptdma-dmaengine.c
@@ -100,12 +100,17 @@ static struct pt_dma_desc *pt_handle_active_desc(struct pt_dma_chan *chan,
spin_lock_irqsave(&chan->vc.lock, flags);
if (desc) {
- if (desc->status != DMA_ERROR)
- desc->status = DMA_COMPLETE;
-
- dma_cookie_complete(tx_desc);
- dma_descriptor_unmap(tx_desc);
- list_del(&desc->vd.node);
+ if (desc->status != DMA_COMPLETE) {
+ if (desc->status != DMA_ERROR)
+ desc->status = DMA_COMPLETE;
+
+ dma_cookie_complete(tx_desc);
+ dma_descriptor_unmap(tx_desc);
+ list_del(&desc->vd.node);
+ } else {
+ /* Don't handle it twice */
+ tx_desc = NULL;
+ }
}
desc = pt_next_dma_desc(chan);
@@ -233,9 +238,14 @@ static void pt_issue_pending(struct dma_chan *dma_chan)
struct pt_dma_chan *chan = to_pt_chan(dma_chan);
struct pt_dma_desc *desc;
unsigned long flags;
+ bool engine_is_idle = true;
spin_lock_irqsave(&chan->vc.lock, flags);
+ desc = pt_next_dma_desc(chan);
+ if (desc)
+ engine_is_idle = false;
+
vchan_issue_pending(&chan->vc);
desc = pt_next_dma_desc(chan);
@@ -243,7 +253,7 @@ static void pt_issue_pending(struct dma_chan *dma_chan)
spin_unlock_irqrestore(&chan->vc.lock, flags);
/* If there was nothing active, start processing */
- if (desc)
+ if (engine_is_idle)
pt_cmd_callback(desc, 0);
}
diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 83a37a6955a3..d2365fab1b7a 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -1389,6 +1389,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
dd->copy_align = DMAENGINE_ALIGN_32_BYTES;
dd->max_burst = STM32_DMA_MAX_BURST;
+ dd->max_sg_burst = STM32_DMA_ALIGNED_MAX_DATA_ITEMS;
dd->descriptor_reuse = true;
dd->dev = &pdev->dev;
INIT_LIST_HEAD(&dd->channels);