Commit 279f4f8f authored by lionel.debieve@st.com's avatar lionel.debieve@st.com Committed by Herbert Xu

hwrng: stm32 - rework read timeout calculation

Increase timeout delay to support longer timing linked
to rng initialization. Measurement is based on timer instead
of instructions per iteration which is not powerful on all
targets.
Signed-off-by: default avatarLionel Debieve <lionel.debieve@st.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent a888df9b
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/hw_random.h> #include <linux/hw_random.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_address.h> #include <linux/of_address.h>
...@@ -35,15 +36,6 @@ ...@@ -35,15 +36,6 @@
#define RNG_DR 0x08 #define RNG_DR 0x08
/*
* It takes 40 cycles @ 48MHz to generate each random number (e.g. <1us).
* At the time of writing STM32 parts max out at ~200MHz meaning a timeout
* of 500 leaves us a very comfortable margin for error. The loop to which
* the timeout applies takes at least 4 instructions per iteration so the
* timeout is enough to take us up to multi-GHz parts!
*/
#define RNG_TIMEOUT 500
struct stm32_rng_private { struct stm32_rng_private {
struct hwrng rng; struct hwrng rng;
void __iomem *base; void __iomem *base;
...@@ -63,13 +55,16 @@ static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) ...@@ -63,13 +55,16 @@ static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
while (max > sizeof(u32)) { while (max > sizeof(u32)) {
sr = readl_relaxed(priv->base + RNG_SR); sr = readl_relaxed(priv->base + RNG_SR);
/* Manage timeout which is based on timer and take */
/* care of initial delay time when enabling rng */
if (!sr && wait) { if (!sr && wait) {
unsigned int timeout = RNG_TIMEOUT; retval = readl_relaxed_poll_timeout_atomic(priv->base
+ RNG_SR,
do { sr, sr,
cpu_relax(); 10, 50000);
sr = readl_relaxed(priv->base + RNG_SR); if (retval)
} while (!sr && --timeout); dev_err((struct device *)priv->rng.priv,
"%s: timeout %x!\n", __func__, sr);
} }
/* If error detected or data not ready... */ /* If error detected or data not ready... */
......
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