Commit bbf2cb1e authored by Nicolas Toromanoff's avatar Nicolas Toromanoff Committed by Herbert Xu

crypto: stm32/crc32 - Avoid lock if hardware is already used

If STM32 CRC device is already in use, calculate CRC by software.

This will release CPU constraint for a concurrent access to the
hardware, and avoid masking irqs during the whole block processing.

Fixes: 7795c0ba ("crypto: stm32/crc32 - protect from concurrent accesses")
Signed-off-by: default avatarNicolas Toromanoff <nicolas.toromanoff@st.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent c4c75fcb
...@@ -3,6 +3,7 @@ config CRYPTO_DEV_STM32_CRC ...@@ -3,6 +3,7 @@ config CRYPTO_DEV_STM32_CRC
tristate "Support for STM32 crc accelerators" tristate "Support for STM32 crc accelerators"
depends on ARCH_STM32 depends on ARCH_STM32
select CRYPTO_HASH select CRYPTO_HASH
select CRC32
help help
This enables support for the CRC32 hw accelerator which can be found This enables support for the CRC32 hw accelerator which can be found
on STMicroelectronics STM32 SOC. on STMicroelectronics STM32 SOC.
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/bitrev.h> #include <linux/bitrev.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/crc32.h>
#include <linux/crc32poly.h> #include <linux/crc32poly.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -149,7 +150,6 @@ static int burst_update(struct shash_desc *desc, const u8 *d8, ...@@ -149,7 +150,6 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,
struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc); struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm); struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
struct stm32_crc *crc; struct stm32_crc *crc;
unsigned long flags;
crc = stm32_crc_get_next_crc(); crc = stm32_crc_get_next_crc();
if (!crc) if (!crc)
...@@ -157,7 +157,15 @@ static int burst_update(struct shash_desc *desc, const u8 *d8, ...@@ -157,7 +157,15 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,
pm_runtime_get_sync(crc->dev); pm_runtime_get_sync(crc->dev);
spin_lock_irqsave(&crc->lock, flags); if (!spin_trylock(&crc->lock)) {
/* Hardware is busy, calculate crc32 by software */
if (mctx->poly == CRC32_POLY_LE)
ctx->partial = crc32_le(ctx->partial, d8, length);
else
ctx->partial = __crc32c_le(ctx->partial, d8, length);
goto pm_out;
}
/* /*
* Restore previously calculated CRC for this context as init value * Restore previously calculated CRC for this context as init value
...@@ -197,8 +205,9 @@ static int burst_update(struct shash_desc *desc, const u8 *d8, ...@@ -197,8 +205,9 @@ static int burst_update(struct shash_desc *desc, const u8 *d8,
/* Store partial result */ /* Store partial result */
ctx->partial = readl_relaxed(crc->regs + CRC_DR); ctx->partial = readl_relaxed(crc->regs + CRC_DR);
spin_unlock_irqrestore(&crc->lock, flags); spin_unlock(&crc->lock);
pm_out:
pm_runtime_mark_last_busy(crc->dev); pm_runtime_mark_last_busy(crc->dev);
pm_runtime_put_autosuspend(crc->dev); pm_runtime_put_autosuspend(crc->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment