MLK-16950 crypto: caam: Fix failed to flush job ring 0
authorAymen Sghaier <aymen.sghaier@nxp.com>
Mon, 27 Nov 2017 16:01:53 +0000 (17:01 +0100)
committerNitin Garg <nitin.garg@nxp.com>
Tue, 20 Mar 2018 19:49:05 +0000 (14:49 -0500)
  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>
drivers/crypto/caam/jr.c

index 16f99d8..3356676 100644 (file)
@@ -31,6 +31,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
@@ -40,9 +41,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) {
@@ -53,8 +56,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);
@@ -403,6 +408,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. */
@@ -414,10 +423,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);