dmagengine: pl330: add code to get reset property
The DMA controller on some SoCs can be held in reset, and thus requires the reset signal(s) to deasserted. Most SoCs will have just one reset signal, but there are others, i.e. Arria10/Stratix10 will have an additional reset signal, referred to as the OCP. Add code to get the reset property from the device tree for deassert and assert. Signed-off-by: Dinh Nguyen <dinguyen@kernel.org> Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Родитель
0ed91bded3
Коммит
0eaab70a7a
|
@ -29,6 +29,7 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
|
#include <linux/reset.h>
|
||||||
|
|
||||||
#include "dmaengine.h"
|
#include "dmaengine.h"
|
||||||
#define PL330_MAX_CHAN 8
|
#define PL330_MAX_CHAN 8
|
||||||
|
@ -500,6 +501,9 @@ struct pl330_dmac {
|
||||||
unsigned int num_peripherals;
|
unsigned int num_peripherals;
|
||||||
struct dma_pl330_chan *peripherals; /* keep at end */
|
struct dma_pl330_chan *peripherals; /* keep at end */
|
||||||
int quirks;
|
int quirks;
|
||||||
|
|
||||||
|
struct reset_control *rstc;
|
||||||
|
struct reset_control *rstc_ocp;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pl330_of_quirks {
|
static struct pl330_of_quirks {
|
||||||
|
@ -3028,6 +3032,32 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
|
||||||
|
|
||||||
amba_set_drvdata(adev, pl330);
|
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++) {
|
for (i = 0; i < AMBA_NR_IRQS; i++) {
|
||||||
irq = adev->irq[i];
|
irq = adev->irq[i];
|
||||||
if (irq) {
|
if (irq) {
|
||||||
|
@ -3168,6 +3198,11 @@ probe_err3:
|
||||||
probe_err2:
|
probe_err2:
|
||||||
pl330_del(pl330);
|
pl330_del(pl330);
|
||||||
|
|
||||||
|
if (pl330->rstc_ocp)
|
||||||
|
reset_control_assert(pl330->rstc_ocp);
|
||||||
|
|
||||||
|
if (pl330->rstc)
|
||||||
|
reset_control_assert(pl330->rstc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3206,6 +3241,11 @@ static int pl330_remove(struct amba_device *adev)
|
||||||
|
|
||||||
pl330_del(pl330);
|
pl330_del(pl330);
|
||||||
|
|
||||||
|
if (pl330->rstc_ocp)
|
||||||
|
reset_control_assert(pl330->rstc_ocp);
|
||||||
|
|
||||||
|
if (pl330->rstc)
|
||||||
|
reset_control_assert(pl330->rstc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче