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:
Родитель
ca25c00ccb
Коммит
06e39357c3
|
@ -4,7 +4,7 @@
|
|||
* JobR backend functionality
|
||||
*
|
||||
* Copyright 2008-2012 Freescale Semiconductor, Inc.
|
||||
* Copyright 2019 NXP
|
||||
* Copyright 2019, 2023 NXP
|
||||
*/
|
||||
|
||||
#include <linux/of_irq.h>
|
||||
|
@ -72,19 +72,27 @@ static void caam_jr_crypto_engine_exit(void *data)
|
|||
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);
|
||||
unsigned int timeout = 100000;
|
||||
|
||||
/*
|
||||
* mask interrupts since we are going to poll
|
||||
* for reset completion status
|
||||
*/
|
||||
clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK);
|
||||
/* Check the current status */
|
||||
if (rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_INPROGRESS)
|
||||
goto wait_quiesce_completion;
|
||||
|
||||
/* initiate flush (required prior to reset) */
|
||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||
/* Reset the field */
|
||||
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) ==
|
||||
JRINT_ERR_HALT_INPROGRESS) && --timeout)
|
||||
cpu_relax();
|
||||
|
@ -95,8 +103,35 @@ static int caam_reset_hw_jr(struct device *dev)
|
|||
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 */
|
||||
timeout = 100000;
|
||||
wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
|
||||
while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
|
||||
cpu_relax();
|
||||
|
|
Загрузка…
Ссылка в новой задаче