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:
Horia Geanta 2023-03-01 00:07:58 +05:30 коммит произвёл Herbert Xu
Родитель ca25c00ccb
Коммит 06e39357c3
1 изменённых файлов: 45 добавлений и 10 удалений

Просмотреть файл

@ -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();