Merge tag 'dmaengine-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:
 "A fairly small update for the dmaengine subsystem. This has a new ARM
  dmaengine driver and couple of new device support and few driver
  changes:

  New support:
   - Renesas RZ/V2H(P) dma support for r9a09g057
   - Arm DMA-350 driver
   - Tegra Tegra264 ADMA support

  Updates:
   - AMD ptdma driver code removal and optimizations
   - Freescale edma error interrupt handler support"

* tag 'dmaengine-6.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (27 commits)
  dmaengine: idxd: Remove unused pointer and macro
  arm64: dts: renesas: r9a09g057: Add DMAC nodes
  dmaengine: sh: rz-dmac: Add RZ/V2H(P) support
  dmaengine: sh: rz-dmac: Allow for multiple DMACs
  irqchip/renesas-rzv2h: Add rzv2h_icu_register_dma_req()
  dt-bindings: dma: rz-dmac: Document RZ/V2H(P) family of SoCs
  dt-bindings: dma: rz-dmac: Restrict properties for RZ/A1H
  dmaengine: idxd: Narrow the restriction on BATCH to ver. 1 only
  dmaengine: ti: Add NULL check in udma_probe()
  fsldma: Set correct dma_mask based on hw capability
  dmaengine: idxd: Check availability of workqueue allocated by idxd wq driver before using
  dmaengine: xilinx_dma: Set dma_device directions
  dmaengine: tegra210-adma: Add Tegra264 support
  dt-bindings: Document Tegra264 ADMA support
  dmaengine: dw-edma: Add HDMA NATIVE map check
  dmaegnine: fsl-edma: add edma error interrupt handler
  dt-bindings: dma: fsl-edma: increase maxItems of interrupts and interrupt-names
  dmaengine: ARM_DMA350 should depend on ARM/ARM64
  dt-bindings: dma: qcom,bam: Document dma-coherent property
  dmaengine: Add Arm DMA-350 driver
  ...
This commit is contained in:
Linus Torvalds
2025-06-05 08:49:30 -07:00
29 changed files with 1463 additions and 106 deletions
@@ -0,0 +1,44 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/dma/arm,dma-350.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Arm CoreLink DMA-350 Controller
maintainers:
- Robin Murphy <robin.murphy@arm.com>
allOf:
- $ref: dma-controller.yaml#
properties:
compatible:
const: arm,dma-350
reg:
items:
- description: Base and size of the full register map
interrupts:
minItems: 1
items:
- description: Channel 0 interrupt
- description: Channel 1 interrupt
- description: Channel 2 interrupt
- description: Channel 3 interrupt
- description: Channel 4 interrupt
- description: Channel 5 interrupt
- description: Channel 6 interrupt
- description: Channel 7 interrupt
"#dma-cells":
const: 1
description: The cell is the trigger input number
required:
- compatible
- reg
- interrupts
unevaluatedProperties: false
@@ -48,11 +48,11 @@ properties:
interrupts:
minItems: 1
maxItems: 64
maxItems: 65
interrupt-names:
minItems: 1
maxItems: 64
maxItems: 65
"#dma-cells":
description: |
@@ -19,6 +19,7 @@ properties:
- enum:
- nvidia,tegra210-adma
- nvidia,tegra186-adma
- nvidia,tegra264-adma
- items:
- enum:
- nvidia,tegra234-adma
@@ -92,6 +93,7 @@ allOf:
contains:
enum:
- nvidia,tegra186-adma
- nvidia,tegra264-adma
then:
anyOf:
- properties:
@@ -42,6 +42,8 @@ properties:
interrupts:
maxItems: 1
dma-coherent: true
iommus:
minItems: 1
maxItems: 6
@@ -11,19 +11,23 @@ maintainers:
properties:
compatible:
items:
- enum:
- renesas,r7s72100-dmac # RZ/A1H
- renesas,r9a07g043-dmac # RZ/G2UL and RZ/Five
- renesas,r9a07g044-dmac # RZ/G2{L,LC}
- renesas,r9a07g054-dmac # RZ/V2L
- renesas,r9a08g045-dmac # RZ/G3S
- const: renesas,rz-dmac
oneOf:
- items:
- enum:
- renesas,r7s72100-dmac # RZ/A1H
- renesas,r9a07g043-dmac # RZ/G2UL and RZ/Five
- renesas,r9a07g044-dmac # RZ/G2{L,LC}
- renesas,r9a07g054-dmac # RZ/V2L
- renesas,r9a08g045-dmac # RZ/G3S
- const: renesas,rz-dmac
- const: renesas,r9a09g057-dmac # RZ/V2H(P)
reg:
items:
- description: Control and channel register block
- description: DMA extended resource selector block
minItems: 1
interrupts:
maxItems: 17
@@ -52,6 +56,7 @@ properties:
items:
- description: DMA main clock
- description: DMA register access clock
minItems: 1
clock-names:
items:
@@ -61,10 +66,10 @@ properties:
'#dma-cells':
const: 1
description:
The cell specifies the encoded MID/RID values of the DMAC port
connected to the DMA client and the slave channel configuration
parameters.
bits[0:9] - Specifies MID/RID value
The cell specifies the encoded MID/RID or the REQ No values of
the DMAC port connected to the DMA client and the slave channel
configuration parameters.
bits[0:9] - Specifies the MID/RID or the REQ No value
bit[10] - Specifies DMA request high enable (HIEN)
bit[11] - Specifies DMA request detection type (LVL)
bits[12:14] - Specifies DMAACK output mode (AM)
@@ -80,12 +85,26 @@ properties:
items:
- description: Reset for DMA ARESETN reset terminal
- description: Reset for DMA RST_ASYNC reset terminal
minItems: 1
reset-names:
items:
- const: arst
- const: rst_async
renesas,icu:
description:
It must contain the phandle to the ICU and the index of the DMAC as seen
from the ICU.
$ref: /schemas/types.yaml#/definitions/phandle-array
items:
- items:
- description: Phandle to the ICU node.
- description:
The number of the DMAC as seen from the ICU, i.e. parameter k from
register ICU_DMkSELy. This may differ from the actual DMAC instance
number.
required:
- compatible
- reg
@@ -98,13 +117,25 @@ allOf:
- $ref: dma-controller.yaml#
- if:
not:
properties:
compatible:
contains:
enum:
- renesas,r7s72100-dmac
properties:
compatible:
contains:
enum:
- renesas,r9a07g043-dmac
- renesas,r9a07g044-dmac
- renesas,r9a07g054-dmac
- renesas,r9a08g045-dmac
then:
properties:
reg:
minItems: 2
clocks:
minItems: 2
resets:
minItems: 2
renesas,icu: false
required:
- clocks
- clock-names
@@ -112,6 +143,46 @@ allOf:
- resets
- reset-names
- if:
properties:
compatible:
contains:
const: renesas,r7s72100-dmac
then:
properties:
reg:
minItems: 2
clocks: false
clock-names: false
power-domains: false
resets: false
reset-names: false
renesas,icu: false
- if:
properties:
compatible:
contains:
const: renesas,r9a09g057-dmac
then:
properties:
reg:
maxItems: 1
clocks:
maxItems: 1
resets:
maxItems: 1
clock-names: false
reset-names: false
required:
- clocks
- power-domains
- renesas,icu
- resets
additionalProperties: false
examples:
@@ -172,8 +172,8 @@ Currently, the types available are:
- It's usually used for copying pixel data between host memory and
memory-mapped GPU device memory, such as found on modern PCI video graphics
cards. The most immediate example is the OpenGL API function
``glReadPielx()``, which might require a verbatim copy of a huge framebuffer
from local device memory onto host memory.
``glReadPixels()``, which might require a verbatim copy of a huge
framebuffer from local device memory onto host memory.
- DMA_XOR
+1 -1
View File
@@ -10781,7 +10781,7 @@ F: net/dsa/tag_hellcreek.c
HISILICON DMA DRIVER
M: Zhou Wang <wangzhou1@hisilicon.com>
M: Jie Hai <haijie1@huawei.com>
M: Longfang Liu <liulongfang@huawei.com>
L: dmaengine@vger.kernel.org
S: Maintained
F: drivers/dma/hisi_dma.c
+165
View File
@@ -280,6 +280,171 @@
resets = <&cpg 0x30>;
};
dmac0: dma-controller@11400000 {
compatible = "renesas,r9a09g057-dmac";
reg = <0 0x11400000 0 0x10000>;
interrupts = <GIC_SPI 499 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 89 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 90 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 91 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 92 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 93 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 94 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 95 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 96 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 97 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 98 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 99 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 100 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 101 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 102 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 103 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 104 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "error",
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5", "ch6", "ch7",
"ch8", "ch9", "ch10", "ch11",
"ch12", "ch13", "ch14", "ch15";
clocks = <&cpg CPG_MOD 0x0>;
power-domains = <&cpg>;
resets = <&cpg 0x31>;
#dma-cells = <1>;
dma-channels = <16>;
renesas,icu = <&icu 4>;
};
dmac1: dma-controller@14830000 {
compatible = "renesas,r9a09g057-dmac";
reg = <0 0x14830000 0 0x10000>;
interrupts = <GIC_SPI 495 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 26 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 27 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 28 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 29 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 30 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 31 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 32 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 33 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 39 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 40 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "error",
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5", "ch6", "ch7",
"ch8", "ch9", "ch10", "ch11",
"ch12", "ch13", "ch14", "ch15";
clocks = <&cpg CPG_MOD 0x1>;
power-domains = <&cpg>;
resets = <&cpg 0x32>;
#dma-cells = <1>;
dma-channels = <16>;
renesas,icu = <&icu 0>;
};
dmac2: dma-controller@14840000 {
compatible = "renesas,r9a09g057-dmac";
reg = <0 0x14840000 0 0x10000>;
interrupts = <GIC_SPI 496 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 41 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 42 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 43 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 45 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 46 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 47 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 48 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 49 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 50 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 51 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 52 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 53 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 54 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 55 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 56 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "error",
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5", "ch6", "ch7",
"ch8", "ch9", "ch10", "ch11",
"ch12", "ch13", "ch14", "ch15";
clocks = <&cpg CPG_MOD 0x2>;
power-domains = <&cpg>;
resets = <&cpg 0x33>;
#dma-cells = <1>;
dma-channels = <16>;
renesas,icu = <&icu 1>;
};
dmac3: dma-controller@12000000 {
compatible = "renesas,r9a09g057-dmac";
reg = <0 0x12000000 0 0x10000>;
interrupts = <GIC_SPI 497 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 57 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 58 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 59 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 60 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 61 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 62 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 63 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 64 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 65 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 66 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 67 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 68 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 69 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 70 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 71 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 72 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "error",
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5", "ch6", "ch7",
"ch8", "ch9", "ch10", "ch11",
"ch12", "ch13", "ch14", "ch15";
clocks = <&cpg CPG_MOD 0x3>;
power-domains = <&cpg>;
resets = <&cpg 0x34>;
#dma-cells = <1>;
dma-channels = <16>;
renesas,icu = <&icu 2>;
};
dmac4: dma-controller@12010000 {
compatible = "renesas,r9a09g057-dmac";
reg = <0 0x12010000 0 0x10000>;
interrupts = <GIC_SPI 498 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 73 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 76 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 77 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 78 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 79 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 80 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 81 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 82 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 83 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 84 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 85 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 86 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 87 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "error",
"ch0", "ch1", "ch2", "ch3",
"ch4", "ch5", "ch6", "ch7",
"ch8", "ch9", "ch10", "ch11",
"ch12", "ch13", "ch14", "ch15";
clocks = <&cpg CPG_MOD 0x4>;
power-domains = <&cpg>;
resets = <&cpg 0x35>;
#dma-cells = <1>;
dma-channels = <16>;
renesas,icu = <&icu 3>;
};
ostm0: timer@11800000 {
compatible = "renesas,r9a09g057-ostm", "renesas,ostm";
reg = <0x0 0x11800000 0x0 0x1000>;
+8
View File
@@ -93,6 +93,14 @@ config APPLE_ADMAC
help
Enable support for Audio DMA Controller found on Apple Silicon SoCs.
config ARM_DMA350
tristate "Arm DMA-350 support"
depends on ARM || ARM64 || COMPILE_TEST
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS
help
Enable support for the Arm DMA-350 controller.
config AT_HDMAC
tristate "Atmel AHB DMA support"
depends on ARCH_AT91
+1
View File
@@ -17,6 +17,7 @@ obj-$(CONFIG_ALTERA_MSGDMA) += altera-msgdma.o
obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
obj-$(CONFIG_APPLE_ADMAC) += apple-admac.o
obj-$(CONFIG_ARM_DMA350) += arm-dma350.o
obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
obj-$(CONFIG_AT_XDMAC) += at_xdmac.o
obj-$(CONFIG_AXI_DMAC) += dma-axi-dmac.o
+4 -19
View File
@@ -566,7 +566,6 @@ int pt_dmaengine_register(struct pt_device *pt)
struct ae4_device *ae4 = NULL;
struct pt_dma_chan *chan;
char *desc_cache_name;
char *cmd_cache_name;
int ret, i;
if (pt->ver == AE4_DMA_VERSION)
@@ -582,27 +581,17 @@ int pt_dmaengine_register(struct pt_device *pt)
if (!pt->pt_dma_chan)
return -ENOMEM;
cmd_cache_name = devm_kasprintf(pt->dev, GFP_KERNEL,
"%s-dmaengine-cmd-cache",
dev_name(pt->dev));
if (!cmd_cache_name)
return -ENOMEM;
desc_cache_name = devm_kasprintf(pt->dev, GFP_KERNEL,
"%s-dmaengine-desc-cache",
dev_name(pt->dev));
if (!desc_cache_name) {
ret = -ENOMEM;
goto err_cache;
}
if (!desc_cache_name)
return -ENOMEM;
pt->dma_desc_cache = kmem_cache_create(desc_cache_name,
sizeof(struct pt_dma_desc), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!pt->dma_desc_cache) {
ret = -ENOMEM;
goto err_cache;
}
if (!pt->dma_desc_cache)
return -ENOMEM;
dma_dev->dev = pt->dev;
dma_dev->src_addr_widths = DMA_SLAVE_BUSWIDTH_64_BYTES;
@@ -656,9 +645,6 @@ int pt_dmaengine_register(struct pt_device *pt)
err_reg:
kmem_cache_destroy(pt->dma_desc_cache);
err_cache:
kmem_cache_destroy(pt->dma_cmd_cache);
return ret;
}
EXPORT_SYMBOL_GPL(pt_dmaengine_register);
@@ -670,5 +656,4 @@ void pt_dmaengine_unregister(struct pt_device *pt)
dma_async_device_unregister(dma_dev);
kmem_cache_destroy(pt->dma_desc_cache);
kmem_cache_destroy(pt->dma_cmd_cache);
}
-1
View File
@@ -254,7 +254,6 @@ struct pt_device {
/* Support for the DMA Engine capabilities */
struct dma_device dma_dev;
struct pt_dma_chan *pt_dma_chan;
struct kmem_cache *dma_cmd_cache;
struct kmem_cache *dma_desc_cache;
wait_queue_head_t lsb_queue;
File diff suppressed because it is too large Load Diff
+2 -4
View File
@@ -2033,10 +2033,8 @@ static int at_xdmac_device_terminate_all(struct dma_chan *chan)
* at_xdmac_start_xfer() for this descriptor. Now it's time
* to release it.
*/
if (desc->active_xfer) {
pm_runtime_put_autosuspend(atxdmac->dev);
pm_runtime_mark_last_busy(atxdmac->dev);
}
if (desc->active_xfer)
pm_runtime_put_noidle(atxdmac->dev);
}
clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status);
+4 -1
View File
@@ -136,7 +136,8 @@ static void dw_edma_pcie_get_vsec_dma_data(struct pci_dev *pdev,
map = FIELD_GET(DW_PCIE_VSEC_DMA_MAP, val);
if (map != EDMA_MF_EDMA_LEGACY &&
map != EDMA_MF_EDMA_UNROLL &&
map != EDMA_MF_HDMA_COMPAT)
map != EDMA_MF_HDMA_COMPAT &&
map != EDMA_MF_HDMA_NATIVE)
return;
pdata->mf = map;
@@ -291,6 +292,8 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev,
pci_dbg(pdev, "Version:\teDMA Unroll (0x%x)\n", chip->mf);
else if (chip->mf == EDMA_MF_HDMA_COMPAT)
pci_dbg(pdev, "Version:\tHDMA Compatible (0x%x)\n", chip->mf);
else if (chip->mf == EDMA_MF_HDMA_NATIVE)
pci_dbg(pdev, "Version:\tHDMA Native (0x%x)\n", chip->mf);
else
pci_dbg(pdev, "Version:\tUnknown (0x%x)\n", chip->mf);
+22 -8
View File
@@ -95,7 +95,7 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan)
}
val = edma_readl_chreg(fsl_chan, ch_csr);
val |= EDMA_V3_CH_CSR_ERQ;
val |= EDMA_V3_CH_CSR_ERQ | EDMA_V3_CH_CSR_EEI;
edma_writel_chreg(fsl_chan, val, ch_csr);
}
@@ -821,7 +821,7 @@ void fsl_edma_issue_pending(struct dma_chan *chan)
int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
{
struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
int ret;
int ret = 0;
if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
clk_prepare_enable(fsl_chan->clk);
@@ -831,17 +831,29 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd),
32, 0);
if (fsl_chan->txirq) {
if (fsl_chan->txirq)
ret = request_irq(fsl_chan->txirq, fsl_chan->irq_handler, IRQF_SHARED,
fsl_chan->chan_name, fsl_chan);
if (ret) {
dma_pool_destroy(fsl_chan->tcd_pool);
return ret;
}
}
if (ret)
goto err_txirq;
if (fsl_chan->errirq > 0)
ret = request_irq(fsl_chan->errirq, fsl_chan->errirq_handler, IRQF_SHARED,
fsl_chan->errirq_name, fsl_chan);
if (ret)
goto err_errirq;
return 0;
err_errirq:
if (fsl_chan->txirq)
free_irq(fsl_chan->txirq, fsl_chan);
err_txirq:
dma_pool_destroy(fsl_chan->tcd_pool);
return ret;
}
void fsl_edma_free_chan_resources(struct dma_chan *chan)
@@ -862,6 +874,8 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
if (fsl_chan->txirq)
free_irq(fsl_chan->txirq, fsl_chan);
if (fsl_chan->errirq)
free_irq(fsl_chan->errirq, fsl_chan);
vchan_dma_desc_free_list(&fsl_chan->vchan, &head);
dma_pool_destroy(fsl_chan->tcd_pool);
+18
View File
@@ -71,6 +71,18 @@
#define EDMA_V3_CH_ES_ERR BIT(31)
#define EDMA_V3_MP_ES_VLD BIT(31)
#define EDMA_V3_CH_ERR_DBE BIT(0)
#define EDMA_V3_CH_ERR_SBE BIT(1)
#define EDMA_V3_CH_ERR_SGE BIT(2)
#define EDMA_V3_CH_ERR_NCE BIT(3)
#define EDMA_V3_CH_ERR_DOE BIT(4)
#define EDMA_V3_CH_ERR_DAE BIT(5)
#define EDMA_V3_CH_ERR_SOE BIT(6)
#define EDMA_V3_CH_ERR_SAE BIT(7)
#define EDMA_V3_CH_ERR_ECX BIT(8)
#define EDMA_V3_CH_ERR_UCE BIT(9)
#define EDMA_V3_CH_ERR BIT(31)
enum fsl_edma_pm_state {
RUNNING = 0,
SUSPENDED,
@@ -162,6 +174,7 @@ struct fsl_edma_chan {
u32 dma_dev_size;
enum dma_data_direction dma_dir;
char chan_name[32];
char errirq_name[36];
void __iomem *tcd;
void __iomem *mux_addr;
u32 real_count;
@@ -174,7 +187,9 @@ struct fsl_edma_chan {
int priority;
int hw_chanid;
int txirq;
int errirq;
irqreturn_t (*irq_handler)(int irq, void *dev_id);
irqreturn_t (*errirq_handler)(int irq, void *dev_id);
bool is_rxchan;
bool is_remote;
bool is_multi_fifo;
@@ -208,6 +223,9 @@ struct fsl_edma_desc {
/* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
#define FSL_EDMA_DRV_CLEAR_DONE_E_LINK BIT(14)
#define FSL_EDMA_DRV_TCD64 BIT(15)
/* All channel ERR IRQ share one IRQ line */
#define FSL_EDMA_DRV_ERRIRQ_SHARE BIT(16)
#define FSL_EDMA_DRV_EDMA3 (FSL_EDMA_DRV_SPLIT_REG | \
FSL_EDMA_DRV_BUS_8BYTE | \
+109 -5
View File
@@ -50,6 +50,83 @@ static irqreturn_t fsl_edma_tx_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void fsl_edma3_err_check(struct fsl_edma_chan *fsl_chan)
{
unsigned int ch_err;
u32 val;
scoped_guard(spinlock, &fsl_chan->vchan.lock) {
ch_err = edma_readl_chreg(fsl_chan, ch_es);
if (!(ch_err & EDMA_V3_CH_ERR))
return;
edma_writel_chreg(fsl_chan, EDMA_V3_CH_ERR, ch_es);
val = edma_readl_chreg(fsl_chan, ch_csr);
val &= ~EDMA_V3_CH_CSR_ERQ;
edma_writel_chreg(fsl_chan, val, ch_csr);
}
/* Ignore this interrupt since channel has been disabled already */
if (!fsl_chan->edesc)
return;
if (ch_err & EDMA_V3_CH_ERR_DBE)
dev_err(&fsl_chan->pdev->dev, "Destination Bus Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_SBE)
dev_err(&fsl_chan->pdev->dev, "Source Bus Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_SGE)
dev_err(&fsl_chan->pdev->dev, "Scatter/Gather Configuration Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_NCE)
dev_err(&fsl_chan->pdev->dev, "NBYTES/CITER Configuration Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_DOE)
dev_err(&fsl_chan->pdev->dev, "Destination Offset Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_DAE)
dev_err(&fsl_chan->pdev->dev, "Destination Address Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_SOE)
dev_err(&fsl_chan->pdev->dev, "Source Offset Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_SAE)
dev_err(&fsl_chan->pdev->dev, "Source Address Error interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_ECX)
dev_err(&fsl_chan->pdev->dev, "Transfer Canceled interrupt.\n");
if (ch_err & EDMA_V3_CH_ERR_UCE)
dev_err(&fsl_chan->pdev->dev, "Uncorrectable TCD error during channel execution interrupt.\n");
fsl_chan->status = DMA_ERROR;
}
static irqreturn_t fsl_edma3_err_handler_per_chan(int irq, void *dev_id)
{
struct fsl_edma_chan *fsl_chan = dev_id;
fsl_edma3_err_check(fsl_chan);
return IRQ_HANDLED;
}
static irqreturn_t fsl_edma3_err_handler_shared(int irq, void *dev_id)
{
struct fsl_edma_engine *fsl_edma = dev_id;
unsigned int ch;
for (ch = 0; ch < fsl_edma->n_chans; ch++) {
if (fsl_edma->chan_masked & BIT(ch))
continue;
fsl_edma3_err_check(&fsl_edma->chans[ch]);
}
return IRQ_HANDLED;
}
static irqreturn_t fsl_edma3_tx_handler(int irq, void *dev_id)
{
struct fsl_edma_chan *fsl_chan = dev_id;
@@ -309,7 +386,8 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma
static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
{
int i;
char *errirq_name;
int i, ret;
for (i = 0; i < fsl_edma->n_chans; i++) {
@@ -324,6 +402,27 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi
return -EINVAL;
fsl_chan->irq_handler = fsl_edma3_tx_handler;
if (!(fsl_edma->drvdata->flags & FSL_EDMA_DRV_ERRIRQ_SHARE)) {
fsl_chan->errirq = fsl_chan->txirq;
fsl_chan->errirq_handler = fsl_edma3_err_handler_per_chan;
}
}
/* All channel err use one irq number */
if (fsl_edma->drvdata->flags & FSL_EDMA_DRV_ERRIRQ_SHARE) {
/* last one is error irq */
fsl_edma->errirq = platform_get_irq_optional(pdev, fsl_edma->n_chans);
if (fsl_edma->errirq < 0)
return 0; /* dts miss err irq, treat as no err irq case */
errirq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-err",
dev_name(&pdev->dev));
ret = devm_request_irq(&pdev->dev, fsl_edma->errirq, fsl_edma3_err_handler_shared,
0, errirq_name, fsl_edma);
if (ret)
return dev_err_probe(&pdev->dev, ret, "Can't register eDMA err IRQ.\n");
}
return 0;
@@ -464,7 +563,8 @@ static struct fsl_edma_drvdata imx7ulp_data = {
};
static struct fsl_edma_drvdata imx8qm_data = {
.flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE,
.flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE
| FSL_EDMA_DRV_ERRIRQ_SHARE,
.chreg_space_sz = 0x10000,
.chreg_off = 0x10000,
.setup_irq = fsl_edma3_irq_init,
@@ -481,14 +581,15 @@ static struct fsl_edma_drvdata imx8ulp_data = {
};
static struct fsl_edma_drvdata imx93_data3 = {
.flags = FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3,
.flags = FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_ERRIRQ_SHARE,
.chreg_space_sz = 0x10000,
.chreg_off = 0x10000,
.setup_irq = fsl_edma3_irq_init,
};
static struct fsl_edma_drvdata imx93_data4 = {
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4,
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4
| FSL_EDMA_DRV_ERRIRQ_SHARE,
.chreg_space_sz = 0x8000,
.chreg_off = 0x10000,
.mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux),
@@ -498,7 +599,7 @@ static struct fsl_edma_drvdata imx93_data4 = {
static struct fsl_edma_drvdata imx95_data5 = {
.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4 |
FSL_EDMA_DRV_TCD64,
FSL_EDMA_DRV_TCD64 | FSL_EDMA_DRV_ERRIRQ_SHARE,
.chreg_space_sz = 0x8000,
.chreg_off = 0x10000,
.mux_off = 0x200,
@@ -700,6 +801,9 @@ static int fsl_edma_probe(struct platform_device *pdev)
snprintf(fsl_chan->chan_name, sizeof(fsl_chan->chan_name), "%s-CH%02d",
dev_name(&pdev->dev), i);
snprintf(fsl_chan->errirq_name, sizeof(fsl_chan->errirq_name),
"%s-CH%02d-err", dev_name(&pdev->dev), i);
fsl_chan->edma = fsl_edma;
fsl_chan->pm_state = RUNNING;
fsl_chan->srcid = 0;
+16 -4
View File
@@ -1226,6 +1226,8 @@ static int fsldma_of_probe(struct platform_device *op)
fdev->dev = &op->dev;
INIT_LIST_HEAD(&fdev->common.channels);
/* The DMA address bits supported for this device. */
fdev->addr_bits = (long)device_get_match_data(fdev->dev);
/* ioremap the registers for use */
fdev->regs = of_iomap(op->dev.of_node, 0);
@@ -1254,7 +1256,7 @@ static int fsldma_of_probe(struct platform_device *op)
fdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
fdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
dma_set_mask(&(op->dev), DMA_BIT_MASK(36));
dma_set_mask(&(op->dev), DMA_BIT_MASK(fdev->addr_bits));
platform_set_drvdata(op, fdev);
@@ -1387,10 +1389,20 @@ static const struct dev_pm_ops fsldma_pm_ops = {
};
#endif
/* The .data field is used for dma-bit-mask. */
static const struct of_device_id fsldma_of_ids[] = {
{ .compatible = "fsl,elo3-dma", },
{ .compatible = "fsl,eloplus-dma", },
{ .compatible = "fsl,elo-dma", },
{
.compatible = "fsl,elo3-dma",
.data = (void *)40,
},
{
.compatible = "fsl,eloplus-dma",
.data = (void *)36,
},
{
.compatible = "fsl,elo-dma",
.data = (void *)32,
},
{}
};
MODULE_DEVICE_TABLE(of, fsldma_of_ids);
+1
View File
@@ -124,6 +124,7 @@ struct fsldma_device {
struct fsldma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
u32 feature; /* The same as DMA channels */
int irq; /* Channel IRQ */
int addr_bits; /* DMA addressing bits supported */
};
/* Define macros for fsldma_chan->feature property */

Some files were not shown because too many files have changed in this diff Show More