2015-10-03 20:35:39

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG

This patchset introduces a driver for the STM32 hardware random number
generator.

Daniel Thompson (3):
dt-bindings: Document the STM32 HW RNG bindings
hwrng: stm32 - add support for STM32 HW RNG
ARM: dts: stm32f429: Adopt STM32 RNG driver

.../devicetree/bindings/hwrng/stm32-rng.txt | 21 +++
arch/arm/boot/dts/stm32f429.dtsi | 7 +
drivers/char/hw_random/Kconfig | 12 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/stm32-rng.c | 192 +++++++++++++++++++++
5 files changed, 233 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwrng/stm32-rng.txt
create mode 100644 drivers/char/hw_random/stm32-rng.c

--
2.4.3


2015-10-12 08:21:27

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG

This patchset introduces a driver for the STM32 hardware random number
generator.

v2:

* Moved binding docs from .../hwrng/ to .../rng/ and renamed to match
convention in new directory (Rob Herring).
* Adopted runtime PM and auto-suspend instead of managing the clocks
from the read function (Linus Walleij). Increased bandwidth by ~30%.
* Simplified error detection in main read loop (Linus Walleij, Maxime
Coquelin).
* Only WARN_ONCE() when hardware failure mechanisms trigger (Maxime
Coquelin).
* Simplify end of probe function after cocci warning (Fengguang Wu).
* Switch to devm_hwrng_register.


Daniel Thompson (3):
dt-bindings: Document the STM32 HW RNG bindings
hwrng: stm32 - add support for STM32 HW RNG
ARM: dts: stm32f429: Adopt STM32 RNG driver

.../devicetree/bindings/rng/st,stm32-rng.txt | 21 +++
arch/arm/boot/dts/stm32f429.dtsi | 7 +
drivers/char/hw_random/Kconfig | 12 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/stm32-rng.c | 202 +++++++++++++++++++++
5 files changed, 243 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/st,stm32-rng.txt
create mode 100644 drivers/char/hw_random/stm32-rng.c

--
2.4.3

2015-10-12 08:21:30

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH 3/3] ARM: dts: stm32f429: Adopt STM32 RNG driver

New bindings and driver have been created for STM32 series parts. This
patch integrates this changes.

Signed-off-by: Daniel Thompson <[email protected]>
Acked-by: Maxime Coquelin <[email protected]>
---
arch/arm/boot/dts/stm32f429.dtsi | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index cb0613090243..90081fc22c6c 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -175,6 +175,13 @@
reg = <0x40023800 0x400>;
clocks = <&clk_hse>;
};
+
+ rng: rng@50060800 {
+ compatible = "st,stm32-rng";
+ reg = <0x50060800 0x400>;
+ interrupts = <80>;
+ clocks = <&rcc 0 38>;
+ };
};
};

--
2.4.3

2015-10-12 08:21:28

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH 1/3] dt-bindings: Document the STM32 HW RNG bindings

This adds documentation of device tree bindings for the STM32 hardware
random number generator.

Signed-off-by: Daniel Thompson <[email protected]>
Acked-by: Maxime Coquelin <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
.../devicetree/bindings/rng/st,stm32-rng.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/st,stm32-rng.txt

diff --git a/Documentation/devicetree/bindings/rng/st,stm32-rng.txt b/Documentation/devicetree/bindings/rng/st,stm32-rng.txt
new file mode 100644
index 000000000000..47f04176f93b
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/st,stm32-rng.txt
@@ -0,0 +1,21 @@
+STMicroelectronics STM32 HW RNG
+===============================
+
+The STM32 hardware random number generator is a simple fixed purpose IP and
+is fully separated from other crypto functions.
+
+Required properties:
+
+- compatible : Should be "st,stm32-rng"
+- reg : Should be register base and length as documented in the datasheet
+- interrupts : The designated IRQ line for the RNG
+- clocks : The clock needed to enable the RNG
+
+Example:
+
+ rng: rng@50060800 {
+ compatible = "st,stm32-rng";
+ reg = <0x50060800 0x400>;
+ interrupts = <80>;
+ clocks = <&rcc 0 38>;
+ };
--
2.4.3

2015-10-14 14:28:36

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG

On Mon, Oct 12, 2015 at 09:21:27AM +0100, Daniel Thompson wrote:
> This patchset introduces a driver for the STM32 hardware random number
> generator.
>
> v2:
>
> * Moved binding docs from .../hwrng/ to .../rng/ and renamed to match
> convention in new directory (Rob Herring).
> * Adopted runtime PM and auto-suspend instead of managing the clocks
> from the read function (Linus Walleij). Increased bandwidth by ~30%.
> * Simplified error detection in main read loop (Linus Walleij, Maxime
> Coquelin).
> * Only WARN_ONCE() when hardware failure mechanisms trigger (Maxime
> Coquelin).
> * Simplify end of probe function after cocci warning (Fengguang Wu).
> * Switch to devm_hwrng_register.

All applied. Thanks!
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

2015-10-14 14:46:26

by Maxime Coquelin

[permalink] [raw]
Subject: Re: [PATCH 0/3] hwrng: stm32 - add support for STM32 HW RNG

Herbert,

2015-10-14 16:28 GMT+02:00 Herbert Xu <[email protected]>:
> On Mon, Oct 12, 2015 at 09:21:27AM +0100, Daniel Thompson wrote:
>> This patchset introduces a driver for the STM32 hardware random number
>> generator.
>>
>> v2:
>>
>> * Moved binding docs from .../hwrng/ to .../rng/ and renamed to match
>> convention in new directory (Rob Herring).
>> * Adopted runtime PM and auto-suspend instead of managing the clocks
>> from the read function (Linus Walleij). Increased bandwidth by ~30%.
>> * Simplified error detection in main read loop (Linus Walleij, Maxime
>> Coquelin).
>> * Only WARN_ONCE() when hardware failure mechanisms trigger (Maxime
>> Coquelin).
>> * Simplify end of probe function after cocci warning (Fengguang Wu).
>> * Switch to devm_hwrng_register.
>
> All applied. Thanks!

I see you again have applied the DT patch like for STi three weeks ago.
The DT patch should go through the arm_soc tree to avoid Linus having
to handle conflicts resolution.

Can you please remove these two patches from your tree?
ba25d8b ARM: STi: STiH407: Enable the 2 HW Random Number Generators
for STiH4{07, 10}
b47c9fa ARM: dts: stm32f429: Adopt STM32 RNG driver

Thanks,
Maxime

2015-10-14 15:55:22

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH v3 0/3] hwrng: stm32 - add support for STM32 HW RNG

This patchset introduces a driver for the STM32 hardware random number
generator.

Herbert: I have assumed the v2 version is *so* badly broken (sorry
again for that) that you would probably choose to remove v2
completely and replace it with v3. In a moment I will also
post a patch to fix the build without ripping out v2. Choose
whichever suits you best.

v3:

* Fixed build with CONFIG_PM (Fengguang Wu). Runtime tested as normal
and also build tested on stm32 (which has CONFIG_PM set) and on
x86/COMPILE_TEST with and without CONFIG_PM.

v2:

* Moved binding docs from .../hwrng/ to .../rng/ and renamed to match
convention in new directory (Rob Herring).
* Adopted runtime PM and auto-suspend instead of managing the clocks
from the read function (Linus Walleij). Increased bandwidth by ~30%.
* Simplified error detection in main read loop (Linus Walleij, Maxime
Coquelin).
* Only WARN_ONCE() when hardware failure mechanisms trigger (Maxime
Coquelin).
* Simplify end of probe function after cocci warning (Fengguang Wu).
* Switch to devm_hwrng_register.


Daniel Thompson (3):
dt-bindings: Document the STM32 HW RNG bindings
hwrng: stm32 - add support for STM32 HW RNG
ARM: dts: stm32f429: Adopt STM32 RNG driver

.../devicetree/bindings/rng/st,stm32-rng.txt | 21 +++
arch/arm/boot/dts/stm32f429.dtsi | 7 +
drivers/char/hw_random/Kconfig | 12 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/stm32-rng.c | 202 +++++++++++++++++++++
5 files changed, 243 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/st,stm32-rng.txt
create mode 100644 drivers/char/hw_random/stm32-rng.c

--
2.4.3

2015-10-14 15:55:44

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH v3 1/3] dt-bindings: Document the STM32 HW RNG bindings

This adds documentation of device tree bindings for the STM32 hardware
random number generator.

Signed-off-by: Daniel Thompson <[email protected]>
Acked-by: Maxime Coquelin <[email protected]>
Acked-by: Rob Herring <[email protected]>
---
.../devicetree/bindings/rng/st,stm32-rng.txt | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rng/st,stm32-rng.txt

diff --git a/Documentation/devicetree/bindings/rng/st,stm32-rng.txt b/Documentation/devicetree/bindings/rng/st,stm32-rng.txt
new file mode 100644
index 000000000000..47f04176f93b
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/st,stm32-rng.txt
@@ -0,0 +1,21 @@
+STMicroelectronics STM32 HW RNG
+===============================
+
+The STM32 hardware random number generator is a simple fixed purpose IP and
+is fully separated from other crypto functions.
+
+Required properties:
+
+- compatible : Should be "st,stm32-rng"
+- reg : Should be register base and length as documented in the datasheet
+- interrupts : The designated IRQ line for the RNG
+- clocks : The clock needed to enable the RNG
+
+Example:
+
+ rng: rng@50060800 {
+ compatible = "st,stm32-rng";
+ reg = <0x50060800 0x400>;
+ interrupts = <80>;
+ clocks = <&rcc 0 38>;
+ };
--
2.4.3

2015-10-14 15:55:49

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH v3 3/3] ARM: dts: stm32f429: Adopt STM32 RNG driver

New bindings and driver have been created for STM32 series parts. This
patch integrates this changes.

Signed-off-by: Daniel Thompson <[email protected]>
Acked-by: Maxime Coquelin <[email protected]>
---
arch/arm/boot/dts/stm32f429.dtsi | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index cb0613090243..90081fc22c6c 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -175,6 +175,13 @@
reg = <0x40023800 0x400>;
clocks = <&clk_hse>;
};
+
+ rng: rng@50060800 {
+ compatible = "st,stm32-rng";
+ reg = <0x50060800 0x400>;
+ interrupts = <80>;
+ clocks = <&rcc 0 38>;
+ };
};
};

--
2.4.3

2015-10-14 15:55:45

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH v3 2/3] hwrng: stm32 - add support for STM32 HW RNG

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 <[email protected]>
Reviewed-by: Linus Walleij <[email protected]>
---
drivers/char/hw_random/Kconfig | 12 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/stm32-rng.c | 202 +++++++++++++++++++++++++++++++++++++
3 files changed, 215 insertions(+)
create mode 100644 drivers/char/hw_random/stm32-rng.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index f48cf11c655e..7930cc9b719c 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -359,6 +359,18 @@ config HW_RANDOM_XGENE

If unsure, say Y.

+config HW_RANDOM_STM32
+ tristate "STMicroelectronics STM32 random number generator"
+ depends on HW_RANDOM && (ARCH_STM32 || COMPILE_TEST)
+ help
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on STM32 microcontrollers.
+
+ To compile this driver as a module, choose M here: the
+ module will be called stm32-rng.
+
+ If unsure, say N.
+
endif # HW_RANDOM

config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 055bb01510ad..8b49c0f7abb1 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o
+obj-$(CONFIG_HW_RANDOM_STM32) += stm32-rng.o
diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c
new file mode 100644
index 000000000000..92a810648bd0
--- /dev/null
+++ b/drivers/char/hw_random/stm32-rng.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2015, Daniel Thompson
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#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/pm_runtime.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 iteration 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 sr;
+ int retval = 0;
+
+ pm_runtime_get_sync((struct device *) priv->rng.priv);
+
+ while (max > sizeof(u32)) {
+ sr = readl_relaxed(priv->base + RNG_SR);
+ if (!sr && wait) {
+ unsigned int timeout = RNG_TIMEOUT;
+
+ do {
+ cpu_relax();
+ sr = readl_relaxed(priv->base + RNG_SR);
+ } while (!sr && --timeout);
+ }
+
+ /* If error detected or data not ready... */
+ if (sr != RNG_SR_DRDY)
+ break;
+
+ *(u32 *)data = readl_relaxed(priv->base + RNG_DR);
+
+ retval += sizeof(u32);
+ data += sizeof(u32);
+ max -= sizeof(u32);
+ }
+
+ if (WARN_ONCE(sr & (RNG_SR_SEIS | RNG_SR_CEIS),
+ "bad RNG status - %x\n", sr))
+ writel_relaxed(0, priv->base + RNG_SR);
+
+ pm_runtime_mark_last_busy((struct device *) priv->rng.priv);
+ pm_runtime_put_sync_autosuspend((struct device *) priv->rng.priv);
+
+ return retval || !wait ? retval : -EIO;
+}
+
+static int stm32_rng_init(struct hwrng *rng)
+{
+ struct stm32_rng_private *priv =
+ container_of(rng, struct stm32_rng_private, rng);
+ int err;
+
+ err = clk_prepare_enable(priv->clk);
+ if (err)
+ return err;
+
+ writel_relaxed(RNG_CR_RNGEN, priv->base + RNG_CR);
+
+ /* clear error indicators */
+ writel_relaxed(0, priv->base + RNG_SR);
+
+ return 0;
+}
+
+static void stm32_rng_cleanup(struct hwrng *rng)
+{
+ struct stm32_rng_private *priv =
+ container_of(rng, struct stm32_rng_private, rng);
+
+ writel_relaxed(0, priv->base + RNG_CR);
+ clk_disable_unprepare(priv->clk);
+}
+
+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),
+#ifndef CONFIG_PM
+ priv->rng.init = stm32_rng_init,
+ priv->rng.cleanup = stm32_rng_cleanup,
+#endif
+ priv->rng.read = stm32_rng_read,
+ priv->rng.priv = (unsigned long) dev;
+
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_enable(dev);
+
+ return devm_hwrng_register(dev, &priv->rng);
+}
+
+#ifdef CONFIG_PM
+static int stm32_rng_runtime_suspend(struct device *dev)
+{
+ struct stm32_rng_private *priv = dev_get_drvdata(dev);
+
+ stm32_rng_cleanup(&priv->rng);
+
+ return 0;
+}
+
+static int stm32_rng_runtime_resume(struct device *dev)
+{
+ struct stm32_rng_private *priv = dev_get_drvdata(dev);
+
+ return stm32_rng_init(&priv->rng);
+}
+#endif
+
+static UNIVERSAL_DEV_PM_OPS(stm32_rng_pm_ops, stm32_rng_runtime_suspend,
+ stm32_rng_runtime_resume, NULL);
+
+static const struct of_device_id stm32_rng_match[] = {
+ {
+ .compatible = "st,stm32-rng",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, stm32_rng_match);
+
+static struct platform_driver stm32_rng_driver = {
+ .driver = {
+ .name = "stm32-rng",
+ .pm = &stm32_rng_pm_ops,
+ .of_match_table = stm32_rng_match,
+ },
+ .probe = stm32_rng_probe,
+};
+
+module_platform_driver(stm32_rng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Thompson <[email protected]>");
+MODULE_DESCRIPTION("STMicroelectronics STM32 RNG device driver");
--
2.4.3

2015-10-14 16:05:11

by Daniel Thompson

[permalink] [raw]
Subject: [PATCH] hwrng: stm32 - Fix build with CONFIG_PM

Commit c6a97c42e399 ("hwrng: stm32 - add support for STM32 HW RNG")
was inadequately tested (actually it was tested quite hard so
incompetent would be a better description that inadequate) and does
not compile on platforms with CONFIG_PM set.

Fix this.

Signed-off-by: Daniel Thompson <[email protected]>
---

Notes:
Herbert: This is the diff between v2 and v3 of my STM32 HW RNG
patch. This is partly reassurance of what has changed
and also "just in case" you prefer to simply fix the
problem.

drivers/char/hw_random/stm32-rng.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c
index 7fa3656a5fc5..92a810648bd0 100644
--- a/drivers/char/hw_random/stm32-rng.c
+++ b/drivers/char/hw_random/stm32-rng.c
@@ -160,7 +160,7 @@ static int stm32_rng_probe(struct platform_device *ofdev)
#ifdef CONFIG_PM
static int stm32_rng_runtime_suspend(struct device *dev)
{
- struct stm32_rng_private *priv = dev_get_drvdata(pdev);
+ struct stm32_rng_private *priv = dev_get_drvdata(dev);

stm32_rng_cleanup(&priv->rng);

@@ -169,7 +169,7 @@ static int stm32_rng_runtime_suspend(struct device *dev)

static int stm32_rng_runtime_resume(struct device *dev)
{
- struct stm32_rng_private *priv = dev_get_drvdata(pdev);
+ struct stm32_rng_private *priv = dev_get_drvdata(dev);

return stm32_rng_init(&priv->rng);
}
--
2.4.3

2015-10-15 02:00:47

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH] hwrng: stm32 - Fix build with CONFIG_PM

On Wed, Oct 14, 2015 at 05:04:55PM +0100, Daniel Thompson wrote:
> Commit c6a97c42e399 ("hwrng: stm32 - add support for STM32 HW RNG")
> was inadequately tested (actually it was tested quite hard so
> incompetent would be a better description that inadequate) and does
> not compile on platforms with CONFIG_PM set.
>
> Fix this.
>
> Signed-off-by: Daniel Thompson <[email protected]>

Patch applied. Thanks!
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt