From 43f141406e7cdee3e0ce429d1e12015bbb8eb333 Mon Sep 17 00:00:00 2001 From: Lin Jinhan Date: Thu, 27 Jul 2023 15:38:28 +0800 Subject: [PATCH] crypto: rockchip: Fixed the timeout timer being triggered incorrectly If the time required for a single data calculation exceeds 3 seconds, timeout occurs.The timeout timer should be reset after the CRYPTO irq interrupt is triggered. Change-Id: I21516ba57bfc8eef3b22624e4ed95523d000cee2 Signed-off-by: Lin Jinhan --- drivers/crypto/rockchip/rk_crypto_core.c | 23 ++++++++++++++++--- drivers/crypto/rockchip/rk_crypto_v2_ahash.c | 4 ++++ .../crypto/rockchip/rk_crypto_v2_skcipher.c | 4 ++++ drivers/crypto/rockchip/rk_crypto_v3_ahash.c | 4 ++++ .../crypto/rockchip/rk_crypto_v3_skcipher.c | 4 ++++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/rockchip/rk_crypto_core.c b/drivers/crypto/rockchip/rk_crypto_core.c index 56a50d5c01de..2a9cf2da6372 100644 --- a/drivers/crypto/rockchip/rk_crypto_core.c +++ b/drivers/crypto/rockchip/rk_crypto_core.c @@ -272,9 +272,17 @@ static void start_irq_timer(struct rk_crypto_dev *rk_dev) static void rk_crypto_irq_timer_handle(struct timer_list *t) { struct rk_crypto_dev *rk_dev = from_timer(rk_dev, t, timer); + unsigned long flags; + + spin_lock_irqsave(&rk_dev->lock, flags); rk_dev->err = -ETIMEDOUT; rk_dev->stat.timeout_cnt++; + + rk_unload_data(rk_dev); + + spin_unlock_irqrestore(&rk_dev->lock, flags); + tasklet_schedule(&rk_dev->done_task); } @@ -282,8 +290,12 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { struct rk_crypto_dev *rk_dev = platform_get_drvdata(dev_id); struct rk_alg_ctx *alg_ctx; + unsigned long flags; - spin_lock(&rk_dev->lock); + spin_lock_irqsave(&rk_dev->lock, flags); + + /* reset timeout timer */ + start_irq_timer(rk_dev); alg_ctx = rk_alg_ctx_cast(rk_dev->async_req); @@ -292,9 +304,14 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) if (alg_ctx->ops.irq_handle) alg_ctx->ops.irq_handle(irq, dev_id); - tasklet_schedule(&rk_dev->done_task); + /* already trigger timeout */ + if (rk_dev->err != -ETIMEDOUT) { + spin_unlock_irqrestore(&rk_dev->lock, flags); + tasklet_schedule(&rk_dev->done_task); + } else { + spin_unlock_irqrestore(&rk_dev->lock, flags); + } - spin_unlock(&rk_dev->lock); return IRQ_HANDLED; } diff --git a/drivers/crypto/rockchip/rk_crypto_v2_ahash.c b/drivers/crypto/rockchip/rk_crypto_v2_ahash.c index dd9ea240bac0..919603ff4768 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_ahash.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_ahash.c @@ -58,6 +58,10 @@ static void rk_hash_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_HASH_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static int rk_crypto_irq_handle(int irq, void *dev_id) diff --git a/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c b/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c index 2a4628f9f58a..2bfff0d28771 100644 --- a/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v2_skcipher.c @@ -197,6 +197,10 @@ static void rk_cipher_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_BC_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static void rk_crypto_complete(struct crypto_async_request *base, int err) diff --git a/drivers/crypto/rockchip/rk_crypto_v3_ahash.c b/drivers/crypto/rockchip/rk_crypto_v3_ahash.c index f39026dbc314..0c91b45b2123 100644 --- a/drivers/crypto/rockchip/rk_crypto_v3_ahash.c +++ b/drivers/crypto/rockchip/rk_crypto_v3_ahash.c @@ -63,6 +63,10 @@ static void rk_hash_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_HASH_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static int rk_hash_mid_data_store(struct rk_crypto_dev *rk_dev, struct rk_hash_mid_data *mid_data) diff --git a/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c b/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c index 26d2b714761c..4220e6cbeb14 100644 --- a/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c +++ b/drivers/crypto/rockchip/rk_crypto_v3_skcipher.c @@ -196,6 +196,10 @@ static void rk_cipher_reset(struct rk_crypto_dev *rk_dev) pool_timeout_us); CRYPTO_WRITE(rk_dev, CRYPTO_BC_CTL, 0xffff0000); + + /* clear dma int status */ + tmp = CRYPTO_READ(rk_dev, CRYPTO_DMA_INT_ST); + CRYPTO_WRITE(rk_dev, CRYPTO_DMA_INT_ST, tmp); } static void rk_crypto_complete(struct crypto_async_request *base, int err)