drivers: crypto: caam/jr - Allow quiesce when quiesced
Issues: - Job ring device is busy when do kexec reboot - Failed to flush job ring when do system suspend-resume Fix: Flush the job ring to stop the running jobs. Signed-off-by: Horia Geanta <horia.geanta@nxp.com> Signed-off-by: Franck LENORMAND <franck.lenormand@nxp.com> Reviewed-by: Pankaj Gupta <pankaj.gupta@nxp.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
* JobR backend functionality
|
* JobR backend functionality
|
||||||
*
|
*
|
||||||
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
||||||
* Copyright 2019 NXP
|
* Copyright 2019, 2023 NXP
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/of_irq.h>
|
#include <linux/of_irq.h>
|
||||||
@@ -72,19 +72,27 @@ static void caam_jr_crypto_engine_exit(void *data)
|
|||||||
crypto_engine_exit(jrpriv->engine);
|
crypto_engine_exit(jrpriv->engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int caam_reset_hw_jr(struct device *dev)
|
/*
|
||||||
|
* Put the CAAM in quiesce, ie stop
|
||||||
|
*
|
||||||
|
* Must be called with itr disabled
|
||||||
|
*/
|
||||||
|
static int caam_jr_stop_processing(struct device *dev, u32 jrcr_bits)
|
||||||
{
|
{
|
||||||
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
||||||
unsigned int timeout = 100000;
|
unsigned int timeout = 100000;
|
||||||
|
|
||||||
/*
|
/* Check the current status */
|
||||||
* mask interrupts since we are going to poll
|
if (rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_INPROGRESS)
|
||||||
* for reset completion status
|
goto wait_quiesce_completion;
|
||||||
*/
|
|
||||||
clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK);
|
|
||||||
|
|
||||||
/* initiate flush (required prior to reset) */
|
/* Reset the field */
|
||||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
clrsetbits_32(&jrp->rregs->jrintstatus, JRINT_ERR_HALT_MASK, 0);
|
||||||
|
|
||||||
|
/* initiate flush / park (required prior to reset) */
|
||||||
|
wr_reg32(&jrp->rregs->jrcommand, jrcr_bits);
|
||||||
|
|
||||||
|
wait_quiesce_completion:
|
||||||
while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
|
while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
|
||||||
JRINT_ERR_HALT_INPROGRESS) && --timeout)
|
JRINT_ERR_HALT_INPROGRESS) && --timeout)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
@@ -95,8 +103,35 @@ static int caam_reset_hw_jr(struct device *dev)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush the job ring, so the jobs running will be stopped, jobs queued will be
|
||||||
|
* invalidated and the CAAM will no longer fetch fron input ring.
|
||||||
|
*
|
||||||
|
* Must be called with itr disabled
|
||||||
|
*/
|
||||||
|
static int caam_jr_flush(struct device *dev)
|
||||||
|
{
|
||||||
|
return caam_jr_stop_processing(dev, JRCR_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int caam_reset_hw_jr(struct device *dev)
|
||||||
|
{
|
||||||
|
struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
|
||||||
|
unsigned int timeout = 100000;
|
||||||
|
int err;
|
||||||
|
/*
|
||||||
|
* mask interrupts since we are going to poll
|
||||||
|
* for reset completion status
|
||||||
|
*/
|
||||||
|
clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK);
|
||||||
|
err = caam_jr_flush(dev);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* initiate reset */
|
/* initiate reset */
|
||||||
timeout = 100000;
|
|
||||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||||
while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
|
while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
Reference in New Issue
Block a user