diff options
author | Aymen Sghaier <aymen.sghaier@nxp.com> | 2017-11-27 17:01:53 +0100 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:32:46 +0800 |
commit | aa7b3f51971ec1f60f41fe8ea71870b215376b8a (patch) | |
tree | 4bbc30a0b75eadbd4edae9b0a66d04d8e336f21f | |
parent | 8ebb20cdc5e535f20099af3c47797917367a3086 (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.c | 19 |
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); |