Use polling to detect the end of the rngc self test. This is much simpler than using an interrupt and a completion. The selftest should take approx. 450us. Keep the overhead to a minimum by polling every 500us. (We've already lowered the timeout to 1.5ms.) Signed-off-by: Martin Kaiser <martin@xxxxxxxxx> --- v2: - use shorter timeout and polling interval drivers/char/hw_random/imx-rngc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 8ff3d46674fd..09523936d2af 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -17,6 +17,7 @@ #include <linux/hw_random.h> #include <linux/completion.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/bitfield.h> #define RNGC_VER_ID 0x0000 @@ -101,22 +102,19 @@ static inline void imx_rngc_irq_unmask(struct imx_rngc *rngc) static int imx_rngc_self_test(struct imx_rngc *rngc) { - u32 cmd; + u32 cmd, status; int ret; - imx_rngc_irq_unmask(rngc); - /* run self test */ cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SELF_TEST, rngc->base + RNGC_COMMAND); - ret = wait_for_completion_timeout(&rngc->rng_op_done, - usecs_to_jiffies(RNGC_SELFTEST_TIMEOUT)); - imx_rngc_irq_mask_clear(rngc); - if (!ret) - return -ETIMEDOUT; + ret = readl_poll_timeout(rngc->base + RNGC_STATUS, status, + status & RNGC_STATUS_ST_DONE, 500, RNGC_SELFTEST_TIMEOUT); + if (ret < 0) + return ret; - return rngc->err_reg ? -EIO : 0; + return readl(rngc->base + RNGC_ERROR) ? -EIO : 0; } static int imx_rngc_read(struct hwrng *rng, void *data, size_t max, bool wait) -- 2.39.2