X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=drivers%2Fdma%2Fpl330.c;h=1163af2ba4a36fef2f313dd09236eee4039236de;hb=47ebe00b684c2bc183a766bc33c8b5943bc0df85;hp=56f9fabc99c46e9ae388d6cdc1d697d3d3e9a4ee;hpb=ba6d10ab8014ac10d25ca513352b6665e73b5785;p=mirror_ubuntu-kernels.git 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 #include #include +#include #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; }