From: Maxime Coquelin <mcoquelin.stm32@gmail.com>
To: Daniel Thompson <daniel.thompson@linaro.org>,
Matt Mackall <mpm@selenic.com>,
Herbert Xu <herbert@gondor.apana.org.au>
Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
patches@linaro.org, linaro-kernel@lists.linaro.org,
Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
Ian Campbell <ijc+devicetree@hellion.org.uk>,
Kumar Gala <galak@codeaurora.org>
Subject: Re: [PATCH 2/3] hwrng: stm32 - add support for STM32 HW RNG
Date: Sun, 4 Oct 2015 10:52:52 +0200 [thread overview]
Message-ID: <5610E8E4.3040507@gmail.com> (raw)
In-Reply-To: <1443904519-24012-3-git-send-email-daniel.thompson@linaro.org>
Hi Daniel,
On 10/03/2015 10:35 PM, Daniel Thompson wrote:
> Add support for STMicroelectronics STM32 random number generator.
>
> The config value defaults to N, reflecting the fact that STM32 is a
> very low resource microcontroller platform and unlikely to be targeted
> by any "grown up" defconfigs.
>
> Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
> ---
> drivers/char/hw_random/Kconfig | 12 +++
> drivers/char/hw_random/Makefile | 1 +
> drivers/char/hw_random/stm32-rng.c | 192 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 205 insertions(+)
> create mode 100644 drivers/char/hw_random/stm32-rng.c
<snip>
> diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c
> new file mode 100644
> index 000000000000..37dfa5fca105
> --- /dev/null
> +++ b/drivers/char/hw_random/stm32-rng.c
> @@ -0,0 +1,192 @@
<snip>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/hw_random.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +
> +#define RNG_CR 0x00
> +#define RNG_CR_RNGEN BIT(2)
> +
> +#define RNG_SR 0x04
> +#define RNG_SR_SEIS BIT(6)
> +#define RNG_SR_CEIS BIT(5)
> +#define RNG_SR_DRDY BIT(0)
> +
> +#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 cycle so the
> + * timeout is enough to take us up to multi-GHz parts!
> + */
> +#define RNG_TIMEOUT 500
> +
> +struct stm32_rng_private {
> + struct hwrng rng;
> + void __iomem *base;
> + struct clk *clk;
> +};
> +
> +static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
> +{
> + struct stm32_rng_private *priv =
> + container_of(rng, struct stm32_rng_private, rng);
> + u32 cr, sr;
> + int retval = 0;
> +
> + /* enable random number generation */
> + clk_enable(priv->clk);
> + cr = readl(priv->base + RNG_CR);
> + writel(cr | RNG_CR_RNGEN, priv->base + RNG_CR);
> +
> + while (max > sizeof(u32)) {
> + sr = readl(priv->base + RNG_SR);
> + if (!sr && wait) {
> + unsigned int timeout = RNG_TIMEOUT;
> +
> + do {
> + cpu_relax();
> + sr = readl(priv->base + RNG_SR);
> + } while (!sr && --timeout);
> + }
> +
> + /* Has h/ware error dection been triggered? */
> + if (WARN_ON(sr & (RNG_SR_SEIS | RNG_SR_CEIS)))
Maybe you should instead use WARN_ONCE?
Because from what I understand in the datasheet, CEIS bit indicates and
error with clock configuration.
If that happens, it is likely the same error will occur each time this
function will be called.
> + break;
> +
> + /* No data ready... */
> + if (!sr)
> + break;
Maybe you could perform this check before the error detection, as if
!sr, the HW error condition will be always false.
> +
> + *(u32 *)data = readl(priv->base + RNG_DR);
> +
> + retval += sizeof(u32);
> + data += sizeof(u32);
> + max -= sizeof(u32);
> + }
> +
> + /* disable the generator */
> + writel(cr, priv->base + RNG_CR);
> + clk_disable(priv->clk);
> +
> + return retval || !wait ? retval : -EIO;
> +}
Couldn't we use "_relaxed" versions of readl/writel?
I might save some not needed barriers.
> +static int stm32_rng_probe(struct platform_device *ofdev)
> +{
> + struct device *dev = &ofdev->dev;
> + struct device_node *np = ofdev->dev.of_node;
> + struct stm32_rng_private *priv;
> + struct resource res;
> + int err;
> +
> + priv = devm_kzalloc(dev, sizeof(struct stm32_rng_private), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + err = of_address_to_resource(np, 0, &res);
> + if (err)
> + return err;
> +
> + priv->base = devm_ioremap_resource(dev, &res);
> + if (IS_ERR(priv->base))
> + return PTR_ERR(priv->base);
> +
> + priv->clk = devm_clk_get(&ofdev->dev, NULL);
> + if (IS_ERR(priv->clk))
> + return PTR_ERR(priv->clk);
> +
> + dev_set_drvdata(dev, priv);
> +
> + priv->rng.name = dev_driver_string(dev),
> + priv->rng.init = stm32_rng_init,
> + priv->rng.cleanup = stm32_rng_cleanup,
> + priv->rng.read = stm32_rng_read,
> + priv->rng.priv = (unsigned long) dev;
> +
> + err = hwrng_register(&priv->rng);
> + if (err)
> + return err;
> +
> + return 0;
As detected with Coccinelle by Fengguang build system, you could simplify:
return hwrng_register(&priv->rng);
Regards,
Maxime
WARNING: multiple messages have this Message-ID (diff)
From: mcoquelin.stm32@gmail.com (Maxime Coquelin)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/3] hwrng: stm32 - add support for STM32 HW RNG
Date: Sun, 4 Oct 2015 10:52:52 +0200 [thread overview]
Message-ID: <5610E8E4.3040507@gmail.com> (raw)
In-Reply-To: <1443904519-24012-3-git-send-email-daniel.thompson@linaro.org>
Hi Daniel,
On 10/03/2015 10:35 PM, Daniel Thompson wrote:
> Add support for STMicroelectronics STM32 random number generator.
>
> The config value defaults to N, reflecting the fact that STM32 is a
> very low resource microcontroller platform and unlikely to be targeted
> by any "grown up" defconfigs.
>
> Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
> ---
> drivers/char/hw_random/Kconfig | 12 +++
> drivers/char/hw_random/Makefile | 1 +
> drivers/char/hw_random/stm32-rng.c | 192 +++++++++++++++++++++++++++++++++++++
> 3 files changed, 205 insertions(+)
> create mode 100644 drivers/char/hw_random/stm32-rng.c
<snip>
> diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c
> new file mode 100644
> index 000000000000..37dfa5fca105
> --- /dev/null
> +++ b/drivers/char/hw_random/stm32-rng.c
> @@ -0,0 +1,192 @@
<snip>
> +#include <linux/clk.h>
> +#include <linux/delay.h>
> +#include <linux/hw_random.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +
> +#define RNG_CR 0x00
> +#define RNG_CR_RNGEN BIT(2)
> +
> +#define RNG_SR 0x04
> +#define RNG_SR_SEIS BIT(6)
> +#define RNG_SR_CEIS BIT(5)
> +#define RNG_SR_DRDY BIT(0)
> +
> +#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 cycle so the
> + * timeout is enough to take us up to multi-GHz parts!
> + */
> +#define RNG_TIMEOUT 500
> +
> +struct stm32_rng_private {
> + struct hwrng rng;
> + void __iomem *base;
> + struct clk *clk;
> +};
> +
> +static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
> +{
> + struct stm32_rng_private *priv =
> + container_of(rng, struct stm32_rng_private, rng);
> + u32 cr, sr;
> + int retval = 0;
> +
> + /* enable random number generation */
> + clk_enable(priv->clk);
> + cr = readl(priv->base + RNG_CR);
> + writel(cr | RNG_CR_RNGEN, priv->base + RNG_CR);
> +
> + while (max > sizeof(u32)) {
> + sr = readl(priv->base + RNG_SR);
> + if (!sr && wait) {
> + unsigned int timeout = RNG_TIMEOUT;
> +
> + do {
> + cpu_relax();
> + sr = readl(priv->base + RNG_SR);
> + } while (!sr && --timeout);
> + }
> +
> + /* Has h/ware error dection been triggered? */
> + if (WARN_ON(sr & (RNG_SR_SEIS | RNG_SR_CEIS)))
Maybe you should instead use WARN_ONCE?
Because from what I understand in the datasheet, CEIS bit indicates and
error with clock configuration.
If that happens, it is likely the same error will occur each time this
function will be called.
> + break;
> +
> + /* No data ready... */
> + if (!sr)
> + break;
Maybe you could perform this check before the error detection, as if
!sr, the HW error condition will be always false.
> +
> + *(u32 *)data = readl(priv->base + RNG_DR);
> +
> + retval += sizeof(u32);
> + data += sizeof(u32);
> + max -= sizeof(u32);
> + }
> +
> + /* disable the generator */
> + writel(cr, priv->base + RNG_CR);
> + clk_disable(priv->clk);
> +
> + return retval || !wait ? retval : -EIO;
> +}
Couldn't we use "_relaxed" versions of readl/writel?
I might save some not needed barriers.
> +static int stm32_rng_probe(struct platform_device *ofdev)
> +{
> + struct device *dev = &ofdev->dev;
> + struct device_node *np = ofdev->dev.of_node;
> + struct stm32_rng_private *priv;
> + struct resource res;
> + int err;
> +
> + priv = devm_kzalloc(dev, sizeof(struct stm32_rng_private), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + err = of_address_to_resource(np, 0, &res);
> + if (err)
> + return err;
> +
> + priv->base = devm_ioremap_resource(dev, &res);
> + if (IS_ERR(priv->base))
> + return PTR_ERR(priv->base);
> +
> + priv->clk = devm_clk_get(&ofdev->dev, NULL);
> + if (IS_ERR(priv->clk))
> + return PTR_ERR(priv->clk);
> +
> + dev_set_drvdata(dev, priv);
> +
> + priv->rng.name = dev_driver_string(dev),
> + priv->rng.init = stm32_rng_init,
> + priv->rng.cleanup = stm32_rng_cleanup,
> + priv->rng.read = stm32_rng_read,
> + priv->rng.priv = (unsigned long) dev;
> +
> + err = hwrng_register(&priv->rng);
> + if (err)
> + return err;
> +
> + return 0;
As detected with Coccinelle by Fengguang build system, you could simplify:
return hwrng_register(&priv->rng);
Regards,
Maxime
next prev parent reply other threads:[~2015-10-04 8:52 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-03 20:35 [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
[not found] ` <1443904519-24012-1-git-send-email-daniel.thompson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-10-03 20:35 ` [PATCH 1/3] dt-bindings: Document the STM32 HW RNG bindings Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
2015-10-04 8:27 ` Maxime Coquelin
2015-10-04 8:27 ` Maxime Coquelin
2015-10-05 15:34 ` Rob Herring
2015-10-05 15:34 ` Rob Herring
2015-10-03 20:35 ` [PATCH 2/3] hwrng: stm32 - add support for STM32 HW RNG Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
2015-10-04 8:52 ` Maxime Coquelin [this message]
2015-10-04 8:52 ` Maxime Coquelin
2015-10-05 9:26 ` Daniel Thompson
2015-10-05 9:26 ` Daniel Thompson
[not found] ` <1443904519-24012-3-git-send-email-daniel.thompson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-10-03 21:02 ` [PATCH] hwrng: fix simple_return.cocci warnings kbuild test robot
2015-10-03 21:02 ` kbuild test robot
2015-10-03 21:02 ` kbuild test robot
2015-10-03 21:02 ` kbuild test robot
2015-10-03 21:02 ` [PATCH 2/3] hwrng: stm32 - add support for STM32 HW RNG kbuild test robot
2015-10-03 21:02 ` kbuild test robot
2015-10-03 21:02 ` kbuild test robot
2015-10-03 21:02 ` kbuild test robot
2015-10-04 10:32 ` Linus Walleij
2015-10-04 10:32 ` Linus Walleij
2015-10-04 10:32 ` Linus Walleij
2015-10-05 9:22 ` Daniel Thompson
2015-10-05 9:22 ` Daniel Thompson
[not found] ` <CAMTL27G9j8tR4WKQgj6HbVCTd-5Xx0HYs40Rij91GgT4D8PevA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-10-11 19:15 ` Daniel Thompson
2015-10-11 19:15 ` Daniel Thompson
2015-10-11 19:15 ` Daniel Thompson
2015-10-11 19:24 ` Daniel Thompson
2015-10-11 19:24 ` Daniel Thompson
2015-10-03 20:35 ` [PATCH 3/3] ARM: dts: stm32f429: Adopt STM32 RNG driver Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
2015-10-03 20:35 ` Daniel Thompson
[not found] ` <1443904519-24012-4-git-send-email-daniel.thompson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-10-04 9:09 ` Maxime Coquelin
2015-10-04 9:09 ` Maxime Coquelin
2015-10-04 9:09 ` Maxime Coquelin
2015-10-12 8:21 ` [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG Daniel Thompson
2015-10-12 8:21 ` Daniel Thompson
2015-10-12 8:21 ` [PATCH 1/3] dt-bindings: Document the STM32 HW RNG bindings Daniel Thompson
2015-10-12 8:21 ` Daniel Thompson
2015-10-12 8:21 ` Daniel Thompson
[not found] ` <1444638090-22886-1-git-send-email-daniel.thompson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
2015-10-12 8:21 ` [PATCH 2/3] hwrng: stm32 - add support for STM32 HW RNG Daniel Thompson
2015-10-12 8:21 ` Daniel Thompson
2015-10-12 8:21 ` Daniel Thompson
2015-10-14 7:39 ` Linus Walleij
2015-10-14 7:39 ` Linus Walleij
2015-10-12 8:21 ` [PATCH 3/3] ARM: dts: stm32f429: Adopt STM32 RNG driver Daniel Thompson
2015-10-12 8:21 ` Daniel Thompson
2015-10-14 14:28 ` [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG Herbert Xu
2015-10-14 14:28 ` Herbert Xu
[not found] ` <20151014142822.GF17455-lOAM2aK0SrRLBo1qDEOMRrpzq4S04n8Q@public.gmane.org>
2015-10-14 14:46 ` Maxime Coquelin
2015-10-14 14:46 ` Maxime Coquelin
2015-10-14 14:46 ` Maxime Coquelin
2015-10-14 15:55 ` [PATCH v3 " Daniel Thompson
2015-10-14 15:55 ` Daniel Thompson
2015-10-14 15:55 ` [PATCH v3 1/3] dt-bindings: Document the STM32 HW RNG bindings Daniel Thompson
2015-10-14 15:55 ` Daniel Thompson
2015-10-14 15:55 ` [PATCH v3 2/3] hwrng: stm32 - add support for STM32 HW RNG Daniel Thompson
2015-10-14 15:55 ` Daniel Thompson
2015-10-14 15:55 ` [PATCH v3 3/3] ARM: dts: stm32f429: Adopt STM32 RNG driver Daniel Thompson
2015-10-14 15:55 ` Daniel Thompson
2015-10-14 16:04 ` [PATCH] hwrng: stm32 - Fix build with CONFIG_PM Daniel Thompson
2015-10-14 16:04 ` Daniel Thompson
2015-10-15 2:00 ` Herbert Xu
2015-10-15 2:00 ` Herbert Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5610E8E4.3040507@gmail.com \
--to=mcoquelin.stm32@gmail.com \
--cc=daniel.thompson@linaro.org \
--cc=devicetree@vger.kernel.org \
--cc=galak@codeaurora.org \
--cc=herbert@gondor.apana.org.au \
--cc=ijc+devicetree@hellion.org.uk \
--cc=linaro-kernel@lists.linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mpm@selenic.com \
--cc=patches@linaro.org \
--cc=pawel.moll@arm.com \
--cc=robh+dt@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.