summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAymen Sghaier <aymen.sghaier@nxp.com>2017-11-27 17:01:53 +0100
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:32:46 +0800
commitaa7b3f51971ec1f60f41fe8ea71870b215376b8a (patch)
tree4bbc30a0b75eadbd4edae9b0a66d04d8e336f21f
parent8ebb20cdc5e535f20099af3c47797917367a3086 (diff)
MLK-16950 crypto: caam: Fix failed to flush job ring 0
This error occurred on MX8M-EVK while initializing the first job ring. If the job ring was used before Kernel level, then connecting it to the irq handler could generate error due to its (unknown) previous state. This patch calls the hardware reset function before connecting the irq handler. Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
-rw-r--r--drivers/crypto/caam/jr.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index b82725cf4f72..b96d4db6709b 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -29,6 +29,7 @@ static int caam_reset_hw_jr(struct device *dev)
{
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
unsigned int timeout = 100000;
+ unsigned int reg_value;
/*
* mask interrupts since we are going to poll
@@ -38,9 +39,11 @@ static int caam_reset_hw_jr(struct device *dev)
/* initiate flush (required prior to reset) */
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
- while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
- JRINT_ERR_HALT_INPROGRESS) && --timeout)
+ do {
cpu_relax();
+ reg_value = rd_reg32(&jrp->rregs->jrintstatus);
+ } while (((reg_value & JRINT_ERR_HALT_MASK) ==
+ JRINT_ERR_HALT_INPROGRESS) && --timeout);
if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
JRINT_ERR_HALT_COMPLETE || timeout == 0) {
@@ -51,8 +54,10 @@ static int caam_reset_hw_jr(struct device *dev)
/* initiate reset */
timeout = 100000;
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
- while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
+ do {
cpu_relax();
+ reg_value = rd_reg32(&jrp->rregs->jrcommand);
+ } while ((reg_value & JRCR_RESET) && --timeout);
if (timeout == 0) {
dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
@@ -402,6 +407,10 @@ static int caam_jr_init(struct device *dev)
jrp = dev_get_drvdata(dev);
+ error = caam_reset_hw_jr(dev);
+ if (error)
+ goto out_kill_deq;
+
tasklet_init(&jrp->irqtask, caam_jr_dequeue, (unsigned long)dev);
/* Connect job ring interrupt handler. */
@@ -413,10 +422,6 @@ static int caam_jr_init(struct device *dev)
goto out_kill_deq;
}
- error = caam_reset_hw_jr(dev);
- if (error)
- goto out_free_irq;
-
error = -ENOMEM;
jrp->inpring = dma_alloc_coherent(dev, sizeof(*jrp->inpring) *
JOBR_DEPTH, &inpbusaddr, GFP_KERNEL);