From patchwork Tue Aug 22 15:25:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaiser X-Patchwork-Id: 13361080 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F091BC3DA66 for ; Tue, 22 Aug 2023 15:28:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237068AbjHVP2h (ORCPT ); Tue, 22 Aug 2023 11:28:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232678AbjHVP2h (ORCPT ); Tue, 22 Aug 2023 11:28:37 -0400 Received: from viti.kaiser.cx (viti.kaiser.cx [IPv6:2a01:238:43fe:e600:cd0c:bd4a:7a3:8e9f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B3588CD8; Tue, 22 Aug 2023 08:28:35 -0700 (PDT) Received: from pd956d63d.dip0.t-ipconnect.de ([217.86.214.61] helo=martin-debian-2.paytec.ch) by viti.kaiser.cx with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1qYTJ3-0006li-UF; Tue, 22 Aug 2023 17:28:34 +0200 From: Martin Kaiser To: Herbert Xu Cc: linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Martin Kaiser Subject: [PATCH 1/3] hwrng: imx-rngc - use polling to detect end of self test Date: Tue, 22 Aug 2023 17:25:51 +0200 Message-Id: <20230822152553.190858-2-martin@kaiser.cx> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230822152553.190858-1-martin@kaiser.cx> References: <20230822152553.190858-1-martin@kaiser.cx> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Use polling to detect the end of the rngc self test. This is much simpler than using an interrupt and a completion. Active waiting is no disadvantage here. The self test is run during probe, there's nothing we could do in parallel at this time. Signed-off-by: Martin Kaiser --- drivers/char/hw_random/imx-rngc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index e4b385b01b11..85207535fd12 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #define RNGC_VER_ID 0x0000 @@ -101,21 +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, msecs_to_jiffies(RNGC_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, 1000, RNGC_TIMEOUT * 1000); + 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) From patchwork Tue Aug 22 15:25:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaiser X-Patchwork-Id: 13361081 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E38F5EE49AC for ; Tue, 22 Aug 2023 15:28:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237085AbjHVP2i (ORCPT ); Tue, 22 Aug 2023 11:28:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234992AbjHVP2i (ORCPT ); Tue, 22 Aug 2023 11:28:38 -0400 Received: from viti.kaiser.cx (viti.kaiser.cx [IPv6:2a01:238:43fe:e600:cd0c:bd4a:7a3:8e9f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B915CE4; Tue, 22 Aug 2023 08:28:36 -0700 (PDT) Received: from pd956d63d.dip0.t-ipconnect.de ([217.86.214.61] helo=martin-debian-2.paytec.ch) by viti.kaiser.cx with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1qYTJ4-0006li-T3; Tue, 22 Aug 2023 17:28:34 +0200 From: Martin Kaiser To: Herbert Xu Cc: linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Martin Kaiser Subject: [PATCH 2/3] hwrng: imx-rngc - read status register for error checks Date: Tue, 22 Aug 2023 17:25:52 +0200 Message-Id: <20230822152553.190858-3-martin@kaiser.cx> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230822152553.190858-1-martin@kaiser.cx> References: <20230822152553.190858-1-martin@kaiser.cx> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org The error bit in the status register of the imx-rngc is set for any kind of error. Details about the error can be read from the bits in the error status register. In the imx_rngc_self_test, we just need the info if there was an error or not. We can check the status register, there's no need to read the error status register. Signed-off-by: Martin Kaiser --- drivers/char/hw_random/imx-rngc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 85207535fd12..d2df468fd460 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -114,7 +114,7 @@ static int imx_rngc_self_test(struct imx_rngc *rngc) if (ret < 0) return ret; - return readl(rngc->base + RNGC_ERROR) ? -EIO : 0; + return (status & RNGC_STATUS_ERROR) ? -EIO : 0; } static int imx_rngc_read(struct hwrng *rng, void *data, size_t max, bool wait) From patchwork Tue Aug 22 15:25:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaiser X-Patchwork-Id: 13361082 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5AC0FEE4993 for ; Tue, 22 Aug 2023 15:28:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234992AbjHVP2m (ORCPT ); Tue, 22 Aug 2023 11:28:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237067AbjHVP2j (ORCPT ); Tue, 22 Aug 2023 11:28:39 -0400 Received: from viti.kaiser.cx (viti.kaiser.cx [IPv6:2a01:238:43fe:e600:cd0c:bd4a:7a3:8e9f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 90B9DCDA; Tue, 22 Aug 2023 08:28:37 -0700 (PDT) Received: from pd956d63d.dip0.t-ipconnect.de ([217.86.214.61] helo=martin-debian-2.paytec.ch) by viti.kaiser.cx with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1qYTJ6-0006li-5r; Tue, 22 Aug 2023 17:28:36 +0200 From: Martin Kaiser To: Herbert Xu Cc: linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Martin Kaiser Subject: [PATCH 3/3] hwrng: imx-rngc - use polling to wait for end of seeding Date: Tue, 22 Aug 2023 17:25:53 +0200 Message-Id: <20230822152553.190858-4-martin@kaiser.cx> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230822152553.190858-1-martin@kaiser.cx> References: <20230822152553.190858-1-martin@kaiser.cx> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Use polling to wait until the imx-rngc is properly seeded. We do this only in the init function when the imx-rngc becomes active. Polling is ok at this time, there's nothing else we could do while we're waiting. We can now remove the code for the interrupt and the completion. Signed-off-by: Martin Kaiser --- drivers/char/hw_random/imx-rngc.c | 81 ++++--------------------------- 1 file changed, 9 insertions(+), 72 deletions(-) diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index d2df468fd460..7ab9aada72d0 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c @@ -63,12 +63,6 @@ struct imx_rngc { struct clk *clk; void __iomem *base; struct hwrng rng; - struct completion rng_op_done; - /* - * err_reg is written only by the irq handler and read only - * when interrupts are masked, we need no spinlock - */ - u32 err_reg; }; @@ -91,15 +85,6 @@ static inline void imx_rngc_irq_mask_clear(struct imx_rngc *rngc) writel(cmd, rngc->base + RNGC_COMMAND); } -static inline void imx_rngc_irq_unmask(struct imx_rngc *rngc) -{ - u32 ctrl; - - ctrl = readl(rngc->base + RNGC_CONTROL); - ctrl &= ~(RNGC_CTRL_MASK_DONE | RNGC_CTRL_MASK_ERROR); - writel(ctrl, rngc->base + RNGC_CONTROL); -} - static int imx_rngc_self_test(struct imx_rngc *rngc) { u32 cmd, status; @@ -143,56 +128,32 @@ static int imx_rngc_read(struct hwrng *rng, void *data, size_t max, bool wait) return retval ? retval : -EIO; } -static irqreturn_t imx_rngc_irq(int irq, void *priv) -{ - struct imx_rngc *rngc = (struct imx_rngc *)priv; - u32 status; - - /* - * clearing the interrupt will also clear the error register - * read error and status before clearing - */ - status = readl(rngc->base + RNGC_STATUS); - rngc->err_reg = readl(rngc->base + RNGC_ERROR); - - imx_rngc_irq_mask_clear(rngc); - - if (status & (RNGC_STATUS_SEED_DONE | RNGC_STATUS_ST_DONE)) - complete(&rngc->rng_op_done); - - return IRQ_HANDLED; -} - static int imx_rngc_init(struct hwrng *rng) { struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng); - u32 cmd, ctrl; + u32 cmd, ctrl, status, err_reg; int ret; /* clear error */ cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_CLR_ERR, rngc->base + RNGC_COMMAND); - imx_rngc_irq_unmask(rngc); - /* create seed, repeat while there is some statistical error */ do { /* seed creation */ cmd = readl(rngc->base + RNGC_COMMAND); writel(cmd | RNGC_CMD_SEED, rngc->base + RNGC_COMMAND); - ret = wait_for_completion_timeout(&rngc->rng_op_done, msecs_to_jiffies(RNGC_TIMEOUT)); - if (!ret) { - ret = -ETIMEDOUT; - goto err; - } + ret = readl_poll_timeout(rngc->base + RNGC_STATUS, status, + status & RNGC_STATUS_SEED_DONE, 1000, RNGC_TIMEOUT * 1000); + if (ret < 0) + return ret; - } while (rngc->err_reg == RNGC_ERROR_STATUS_STAT_ERR); + err_reg = readl(rngc->base + RNGC_ERROR); + } while (err_reg == RNGC_ERROR_STATUS_STAT_ERR); - if (rngc->err_reg) { - ret = -EIO; - goto err; - } + if (err_reg) + return -EIO; /* * enable automatic seeding, the rngc creates a new seed automatically @@ -202,23 +163,7 @@ static int imx_rngc_init(struct hwrng *rng) ctrl |= RNGC_CTRL_AUTO_SEED; writel(ctrl, rngc->base + RNGC_CONTROL); - /* - * if initialisation was successful, we keep the interrupt - * unmasked until imx_rngc_cleanup is called - * we mask the interrupt ourselves if we return an error - */ return 0; - -err: - imx_rngc_irq_mask_clear(rngc); - return ret; -} - -static void imx_rngc_cleanup(struct hwrng *rng) -{ - struct imx_rngc *rngc = container_of(rng, struct imx_rngc, rng); - - imx_rngc_irq_mask_clear(rngc); } static int __init imx_rngc_probe(struct platform_device *pdev) @@ -254,12 +199,9 @@ static int __init imx_rngc_probe(struct platform_device *pdev) if (rng_type != RNGC_TYPE_RNGC && rng_type != RNGC_TYPE_RNGB) return -ENODEV; - init_completion(&rngc->rng_op_done); - rngc->rng.name = pdev->name; rngc->rng.init = imx_rngc_init; rngc->rng.read = imx_rngc_read; - rngc->rng.cleanup = imx_rngc_cleanup; rngc->rng.quality = 19; rngc->dev = &pdev->dev; @@ -267,11 +209,6 @@ static int __init imx_rngc_probe(struct platform_device *pdev) imx_rngc_irq_mask_clear(rngc); - ret = devm_request_irq(&pdev->dev, - irq, imx_rngc_irq, 0, pdev->name, (void *)rngc); - if (ret) - return dev_err_probe(&pdev->dev, ret, "Can't get interrupt working.\n"); - if (self_test) { ret = imx_rngc_self_test(rngc); if (ret)