summaryrefslogtreecommitdiff
path: root/drivers/dma/pl330.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-07-17 09:55:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-07-17 09:55:43 -0700
commit47ebe00b684c2bc183a766bc33c8b5943bc0df85 (patch)
treec0f155acc5623f6990d20b7a623f48f5e7aa0f61 /drivers/dma/pl330.c
parentfa121bb3fed6313b1f0af23952301e06cf6d32ed (diff)
parent5c274ca4cfb22a455e880f61536b1894fa29fd17 (diff)
Merge tag 'dmaengine-5.3-rc1' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul: - Add support in dmaengine core to do device node checks for DT devices and update bunch of drivers to use that and remove open coding from drivers - New driver/driver support for new hardware, namely: - MediaTek UART APDMA - Freescale i.mx7ulp edma2 - Synopsys eDMA IP core version 0 - Allwinner H6 DMA - Updates to axi-dma and support for interleaved cyclic transfers - Greg's debugfs return value check removals on drivers - Updates to stm32-dma, hsu, dw, pl330, tegra drivers * tag 'dmaengine-5.3-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (68 commits) dmaengine: Revert "dmaengine: fsl-edma: add i.mx7ulp edma2 version support" dmaengine: at_xdmac: check for non-empty xfers_list before invoking callback Documentation: dmaengine: clean up description of dmatest usage dmaengine: tegra210-adma: remove PM_CLK dependency dmaengine: fsl-edma: add i.mx7ulp edma2 version support dt-bindings: dma: fsl-edma: add new i.mx7ulp-edma dmaengine: fsl-edma-common: version check for v2 instead dmaengine: fsl-edma-common: move dmamux register to another single function dmaengine: fsl-edma: add drvdata for fsl-edma dmaengine: Revert "dmaengine: fsl-edma: support little endian for edma driver" dmaengine: rcar-dmac: Reject zero-length slave DMA requests dmaengine: dw: Enable iDMA 32-bit on Intel Elkhart Lake dmaengine: dw-edma: fix semicolon.cocci warnings dmaengine: sh: usb-dmac: Use [] to denote a flexible array member dmaengine: dmatest: timeout value of -1 should specify infinite wait dmaengine: dw: Distinguish ->remove() between DW and iDMA 32-bit dmaengine: fsl-edma: support little endian for edma driver dmaengine: hsu: Revert "set HSU_CH_MTSR to memory width" dmagengine: pl330: add code to get reset property dt-bindings: pl330: document the optional resets property ...
Diffstat (limited to 'drivers/dma/pl330.c')
-rw-r--r--drivers/dma/pl330.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 56f9fabc99c4..1163af2ba4a3 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -25,6 +25,7 @@
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/bug.h>
+#include <linux/reset.h>
#include "dmaengine.h"
#define PL330_MAX_CHAN 8
@@ -496,6 +497,9 @@ struct pl330_dmac {
unsigned int num_peripherals;
struct dma_pl330_chan *peripherals; /* keep at end */
int quirks;
+
+ struct reset_control *rstc;
+ struct reset_control *rstc_ocp;
};
static struct pl330_of_quirks {
@@ -3024,6 +3028,32 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
amba_set_drvdata(adev, pl330);
+ pl330->rstc = devm_reset_control_get_optional(&adev->dev, "dma");
+ if (IS_ERR(pl330->rstc)) {
+ if (PTR_ERR(pl330->rstc) != -EPROBE_DEFER)
+ dev_err(&adev->dev, "Failed to get reset!\n");
+ return PTR_ERR(pl330->rstc);
+ } else {
+ ret = reset_control_deassert(pl330->rstc);
+ if (ret) {
+ dev_err(&adev->dev, "Couldn't deassert the device from reset!\n");
+ return ret;
+ }
+ }
+
+ pl330->rstc_ocp = devm_reset_control_get_optional(&adev->dev, "dma-ocp");
+ if (IS_ERR(pl330->rstc_ocp)) {
+ if (PTR_ERR(pl330->rstc_ocp) != -EPROBE_DEFER)
+ dev_err(&adev->dev, "Failed to get OCP reset!\n");
+ return PTR_ERR(pl330->rstc_ocp);
+ } else {
+ ret = reset_control_deassert(pl330->rstc_ocp);
+ if (ret) {
+ dev_err(&adev->dev, "Couldn't deassert the device from OCP reset!\n");
+ return ret;
+ }
+ }
+
for (i = 0; i < AMBA_NR_IRQS; i++) {
irq = adev->irq[i];
if (irq) {
@@ -3164,6 +3194,11 @@ probe_err3:
probe_err2:
pl330_del(pl330);
+ if (pl330->rstc_ocp)
+ reset_control_assert(pl330->rstc_ocp);
+
+ if (pl330->rstc)
+ reset_control_assert(pl330->rstc);
return ret;
}
@@ -3202,6 +3237,11 @@ static int pl330_remove(struct amba_device *adev)
pl330_del(pl330);
+ if (pl330->rstc_ocp)
+ reset_control_assert(pl330->rstc_ocp);
+
+ if (pl330->rstc)
+ reset_control_assert(pl330->rstc);
return 0;
}