2013-03-22 12:55:40

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH] hw_random: Add Broadcom BCM2835 RNG Driver

Signed-off-by: Lubomir Rintel <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: Matt Mackall <[email protected]>
Cc: [email protected]
---
arch/arm/boot/dts/bcm2835.dtsi | 5 +
arch/arm/configs/bcm2835_defconfig | 3 +-
drivers/char/hw_random/Kconfig | 12 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/bcm2835-rng.c | 137 ++++++++++++++++++++++++++++++++++
5 files changed, 157 insertions(+), 1 deletions(-)
create mode 100644 drivers/char/hw_random/bcm2835-rng.c

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 7e0481e..dc22336 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -34,6 +34,11 @@
reg = <0x7e100000 0x28>;
};

+ rng {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+ };
+
uart@20201000 {
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
reg = <0x7e201000 0x1000>;
diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index af472e4..611bda2 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -59,7 +59,8 @@ CONFIG_DEVTMPFS_MOUNT=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_TTY_PRINTK=y
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_BCM2835=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_BCM2835=y
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index c5a0262..2f9dbf7 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -86,6 +86,18 @@ config HW_RANDOM_BCM63XX

If unusure, say Y.

+config HW_RANDOM_BCM2835
+ tristate "Broadcom BCM2835 Random Number Generator support"
+ depends on HW_RANDOM && ARCH_BCM2835
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on the Broadcom BCM2835 SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bcm2835-rng
+
+ If unsure, say Y.

config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 1fd7eec..bed467c 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
+obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
new file mode 100644
index 0000000..66adc7f
--- /dev/null
+++ b/drivers/char/hw_random/bcm2835-rng.c
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ * Copyright (c) 2013 Lubomir Rintel
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2, as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/hw_random.h>
+#include <linux/init.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/platform_device.h>
+#include <linux/printk.h>
+
+#define RNG_CTRL 0x0
+#define RNG_STATUS 0x4
+#define RNG_DATA 0x8
+
+/* enable rng */
+#define RNG_RBGEN 0x1
+
+/* the initial numbers generated are "less random" so will be discarded */
+#define RNG_WARMUP_COUNT 0x40000
+
+static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
+ bool wait)
+{
+ void __iomem *rng_base = (void __iomem *)rng->priv;
+
+ while ((__raw_readl(rng_base + RNG_STATUS)>>24) == 0) {
+ if (!wait)
+ return 0;
+ cpu_relax();
+ }
+
+ *(u32 *)buf = __raw_readl(rng_base + RNG_DATA);
+ return sizeof(u32);
+}
+
+static struct hwrng bcm2835_rng_ops = {
+ .name = "bcm2835",
+ .read = bcm2835_rng_read,
+};
+
+static int bcm2835_rng_probe(struct platform_device *op)
+{
+ struct device *dev = &op->dev;
+ struct device_node *np = dev->of_node;
+ void __iomem *rng_base;
+ int err;
+
+ /* map peripheral */
+ rng_base = of_iomap(np, 0);
+ if (WARN(!rng_base, "failed to remap rng regs"))
+ return -ENODEV;
+ bcm2835_rng_ops.priv = (unsigned long)rng_base;
+
+ /* register driver */
+ err = hwrng_register(&bcm2835_rng_ops);
+ if (err) {
+ dev_err(dev, "hwrng registration failed\n");
+ iounmap(rng_base);
+ } else {
+ dev_info(dev, "hwrng registered\n");
+
+ /* set warm-up count & enable */
+ __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+ __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+ }
+ return err;
+}
+
+static int bcm2835_rng_remove(struct platform_device *op)
+{
+ void __iomem *rng_base = (void __iomem *)bcm2835_rng_ops.priv;
+
+ /* disable rng hardware */
+ __raw_writel(0, rng_base + RNG_CTRL);
+
+ /* unregister driver */
+ hwrng_unregister(&bcm2835_rng_ops);
+ iounmap(rng_base);
+
+ return 0;
+}
+
+static const struct of_device_id bcm2835_rng_of_match[] = {
+ { .compatible = "brcm,bcm2835-rng", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match);
+
+static struct platform_driver bcm2835_rng_driver = {
+ .driver = {
+ .name = "bcm2835-rng",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm2835_rng_of_match,
+ },
+ .probe = bcm2835_rng_probe,
+ .remove = bcm2835_rng_remove,
+};
+
+module_platform_driver(bcm2835_rng_driver);
+
+MODULE_AUTHOR("Lubomir Rintel <[email protected]>");
+MODULE_DESCRIPTION("BCM2835 Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPL and additional rights");
--
1.7.1


2013-03-23 02:44:43

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH] hw_random: Add Broadcom BCM2835 RNG Driver

On 03/22/2013 06:55 AM, Lubomir Rintel wrote:
> Signed-off-by: Lubomir Rintel <[email protected]>

A commit description would be useful.

> arch/arm/boot/dts/bcm2835.dtsi | 5 +
> arch/arm/configs/bcm2835_defconfig | 3 +-
> drivers/char/hw_random/Kconfig | 12 +++
> drivers/char/hw_random/Makefile | 1 +
> drivers/char/hw_random/bcm2835-rng.c | 137 ++++++++++++++++++++++++++++++++++

This should be split into 3 separate patches: (1) The driver itself, (2)
the change to bcm2835.dtsi, and (3) the change to bcm2835_defconfig.

Since you're adding a new device to device tree for the first time, you
should write a binding document for it; most likely
Documentation/devicetree/bindings/rng/brcm,bcm2835.txt (or perhaps
/random/ rather than /rng/?)

Is this driver based on the downstream Raspberry Pi kernel's driver? If
so, some mention of that fact would be appropriate in the commit
description, or even the git author field. I note that in the downstream
kernel, the commit which adds the RNG driver isn't signed off at all.
This probably means you need to get Dom to add his signed-off-by line
for that commit before basing your work on it. See
Documentation/SubmittingPatches for more details.

> diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c

> + * Redistribution and use in source and binary forms, with or without
...
> + * ALTERNATIVELY, this software may be distributed under the terms of the
> + * GNU General Public License ("GPL") version 2, as published by the Free
> + * Software Foundation.

I am not a lawyer, but I'd be tempted to exercise that right, and
distribute this patch solely under the terms of the GPLv2, and hence
remove the other license. It's not a big deal, but it'd simplify the
licensing in the upstream kernel.

> +static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
> + bool wait)

> + while ((__raw_readl(rng_base + RNG_STATUS)>>24) == 0) {

You'd usually put spaces around the >>.

> +static int bcm2835_rng_probe(struct platform_device *op)

"pdev" is a more typical name than "op".

> +{
> + struct device *dev = &op->dev;
> + struct device_node *np = dev->of_node;
> + void __iomem *rng_base;
> + int err;
> +
> + /* map peripheral */
> + rng_base = of_iomap(np, 0);
> + if (WARN(!rng_base, "failed to remap rng regs"))
> + return -ENODEV;

The WARN() doesn't seem necessary. dev_err() inside the if{} would be
more appropriate,

> +static struct platform_driver bcm2835_rng_driver = {
...
> +};
> +
> +module_platform_driver(bcm2835_rng_driver);

Typically, no blank line there.

> +MODULE_AUTHOR("Lubomir Rintel <[email protected]>");
> +MODULE_DESCRIPTION("BCM2835 Random Number Generator (RNG) driver");
> +MODULE_LICENSE("GPL and additional rights");

I think that should be "GPLv2 and ...".

2013-03-24 14:31:57

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v2] bcm2835: Add Broadcom BCM2835 RNG to the device tree

This adds a device tree binding for random number generator present on Broadcom
BCM2835 SoC, used in Raspberry Pi and Roku 2 devices.

Signed-off-by: Lubomir Rintel <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: [email protected]
---
Changes for v2:
- Split out from the driver changeset
- Added documentation

.../devicetree/bindings/rng/brcm,bcm2835.txt | 13 +++++++++++++
arch/arm/boot/dts/bcm2835.dtsi | 5 +++++
2 files changed, 18 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/rng/brcm,bcm2835.txt

diff --git a/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt
new file mode 100644
index 0000000..07ccdaa
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt
@@ -0,0 +1,13 @@
+BCM2835 Random number generator
+
+Required properties:
+
+- compatible : should be "brcm,bcm2835-rng"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+rng {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+};
diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 7e0481e..dc22336 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -34,6 +34,11 @@
reg = <0x7e100000 0x28>;
};

+ rng {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+ };
+
uart@20201000 {
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
reg = <0x7e201000 0x1000>;
--
1.7.1

2013-03-24 14:37:10

by Lubomir Rintel

[permalink] [raw]
Subject: Re: [PATCH] hw_random: Add Broadcom BCM2835 RNG Driver

On Fri, 2013-03-22 at 20:44 -0600, Stephen Warren wrote:

Thank you for your response!

> On 03/22/2013 06:55 AM, Lubomir Rintel wrote:
> > Signed-off-by: Lubomir Rintel <lkundrak at v3.sk>
>
> A commit description would be useful.
>
> > arch/arm/boot/dts/bcm2835.dtsi | 5 +
> > arch/arm/configs/bcm2835_defconfig | 3 +-
> > drivers/char/hw_random/Kconfig | 12 +++
> > drivers/char/hw_random/Makefile | 1 +
> > drivers/char/hw_random/bcm2835-rng.c | 137 ++++++++++++++++++++++++++++++++++
>
> This should be split into 3 separate patches: (1) The driver itself, (2)
> the change to bcm2835.dtsi, and (3) the change to bcm2835_defconfig.
>
> Since you're adding a new device to device tree for the first time, you
> should write a binding document for it; most likely
> Documentation/devicetree/bindings/rng/brcm,bcm2835.txt (or perhaps
> /random/ rather than /rng/?)

Okay. I'm tempted to stick to "rng" instead of "random" as it seems more
consistent to me, but I don't have a strong reason to back it with. What would
be a good reason for using "random"?

> Is this driver based on the downstream Raspberry Pi kernel's driver? If
> so, some mention of that fact would be appropriate in the commit
> description, or even the git author field. I note that in the downstream
> kernel, the commit which adds the RNG driver isn't signed off at all.
> This probably means you need to get Dom to add his signed-off-by line
> for that commit before basing your work on it. See
> Documentation/SubmittingPatches for more details.

Ok, will try to.

I'll still follow up with an updated patch, so that it can be reviewed.

> > diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
>
> > + * Redistribution and use in source and binary forms, with or without
> ...
> > + * ALTERNATIVELY, this software may be distributed under the terms of the
> > + * GNU General Public License ("GPL") version 2, as published by the Free
> > + * Software Foundation.
>
> I am not a lawyer, but I'd be tempted to exercise that right, and
> distribute this patch solely under the terms of the GPLv2, and hence
> remove the other license. It's not a big deal, but it'd simplify the
> licensing in the upstream kernel.

Will do.

> > +static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
> > + bool wait)
>
> > + while ((__raw_readl(rng_base + RNG_STATUS)>>24) == 0) {
>
> You'd usually put spaces around the >>.

Will be fixed.

> > +static int bcm2835_rng_probe(struct platform_device *op)
>
> "pdev" is a more typical name than "op".

Will be adjusted.

> > +{
> > + struct device *dev = &op->dev;
> > + struct device_node *np = dev->of_node;
> > + void __iomem *rng_base;
> > + int err;
> > +
> > + /* map peripheral */
> > + rng_base = of_iomap(np, 0);
> > + if (WARN(!rng_base, "failed to remap rng regs"))
> > + return -ENODEV;
>
> The WARN() doesn't seem necessary. dev_err() inside the if{} would be
> more appropriate,

Makes sense, will be adjusted.

> > +static struct platform_driver bcm2835_rng_driver = {
> ...
> > +};
> > +
> > +module_platform_driver(bcm2835_rng_driver);
>
> Typically, no blank line there.

Ok

> > +MODULE_AUTHOR("Lubomir Rintel <lkundrak at v3.sk>");
> > +MODULE_DESCRIPTION("BCM2835 Random Number Generator (RNG) driver");
> > +MODULE_LICENSE("GPL and additional rights");
>
> I think that should be "GPLv2 and ...".

Ok

--
Lubomir Rintel <[email protected]>

2013-03-24 14:39:49

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v2] hw_random: Add Broadcom BCM2835 RNG driver

This adds a driver for random number generator present on Broadcom BCM2835 SoC,
used in Raspberry Pi and Roku 2 devices.

Signed-off-by: Lubomir Rintel <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: Matt Mackall <[email protected]>
Cc: [email protected]
---
Changes for v2:
- Device tree and defconfig changes split out
- Licence changed from GPLv2+BSD to GPLv2 only
- Style fixes

drivers/char/hw_random/Kconfig | 12 ++++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/bcm2835-rng.c | 113 ++++++++++++++++++++++++++++++++++
3 files changed, 126 insertions(+), 0 deletions(-)
create mode 100644 drivers/char/hw_random/bcm2835-rng.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index c5a0262..2f9dbf7 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -86,6 +86,18 @@ config HW_RANDOM_BCM63XX

If unusure, say Y.

+config HW_RANDOM_BCM2835
+ tristate "Broadcom BCM2835 Random Number Generator support"
+ depends on HW_RANDOM && ARCH_BCM2835
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on the Broadcom BCM2835 SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bcm2835-rng
+
+ If unsure, say Y.

config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 1fd7eec..bed467c 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
+obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
new file mode 100644
index 0000000..eb7f147
--- /dev/null
+++ b/drivers/char/hw_random/bcm2835-rng.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ * Copyright (c) 2013 Lubomir Rintel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License ("GPL")
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/hw_random.h>
+#include <linux/init.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/platform_device.h>
+#include <linux/printk.h>
+
+#define RNG_CTRL 0x0
+#define RNG_STATUS 0x4
+#define RNG_DATA 0x8
+
+/* enable rng */
+#define RNG_RBGEN 0x1
+
+/* the initial numbers generated are "less random" so will be discarded */
+#define RNG_WARMUP_COUNT 0x40000
+
+static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
+ bool wait)
+{
+ void __iomem *rng_base = (void __iomem *)rng->priv;
+
+ while ((__raw_readl(rng_base + RNG_STATUS) >> 24) == 0) {
+ if (!wait)
+ return 0;
+ cpu_relax();
+ }
+
+ *(u32 *)buf = __raw_readl(rng_base + RNG_DATA);
+ return sizeof(u32);
+}
+
+static struct hwrng bcm2835_rng_ops = {
+ .name = "bcm2835",
+ .read = bcm2835_rng_read,
+};
+
+static int bcm2835_rng_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ void __iomem *rng_base;
+ int err;
+
+ /* map peripheral */
+ rng_base = of_iomap(np, 0);
+ if (!rng_base) {
+ dev_err(dev, "failed to remap rng regs");
+ return -ENODEV;
+ }
+ bcm2835_rng_ops.priv = (unsigned long)rng_base;
+
+ /* register driver */
+ err = hwrng_register(&bcm2835_rng_ops);
+ if (err) {
+ dev_err(dev, "hwrng registration failed\n");
+ iounmap(rng_base);
+ } else {
+ dev_info(dev, "hwrng registered\n");
+
+ /* set warm-up count & enable */
+ __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+ __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+ }
+ return err;
+}
+
+static int bcm2835_rng_remove(struct platform_device *pdev)
+{
+ void __iomem *rng_base = (void __iomem *)bcm2835_rng_ops.priv;
+
+ /* disable rng hardware */
+ __raw_writel(0, rng_base + RNG_CTRL);
+
+ /* unregister driver */
+ hwrng_unregister(&bcm2835_rng_ops);
+ iounmap(rng_base);
+
+ return 0;
+}
+
+static const struct of_device_id bcm2835_rng_of_match[] = {
+ { .compatible = "brcm,bcm2835-rng", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match);
+
+static struct platform_driver bcm2835_rng_driver = {
+ .driver = {
+ .name = "bcm2835-rng",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm2835_rng_of_match,
+ },
+ .probe = bcm2835_rng_probe,
+ .remove = bcm2835_rng_remove,
+};
+module_platform_driver(bcm2835_rng_driver);
+
+MODULE_AUTHOR("Lubomir Rintel <[email protected]>");
+MODULE_DESCRIPTION("BCM2835 Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPLv2");
--
1.7.1

2013-03-24 14:41:20

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v2] arm: Add Broadcom BCM2835 RNG driver to bcm2835_defconfig

This enables a driver for random number generator present on Broadcom BCM2835 SoC,
used in Raspberry Pi and Roku 2 devices.

Signed-off-by: Lubomir Rintel <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: [email protected]
---
Changes for v2:
- Split out from the driver changeset

arch/arm/configs/bcm2835_defconfig | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig
index af472e4..611bda2 100644
--- a/arch/arm/configs/bcm2835_defconfig
+++ b/arch/arm/configs/bcm2835_defconfig
@@ -59,7 +59,8 @@ CONFIG_DEVTMPFS_MOUNT=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_TTY_PRINTK=y
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_BCM2835=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_BCM2835=y
--
1.7.1

2013-03-27 02:52:06

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH] hw_random: Add Broadcom BCM2835 RNG Driver

On 03/24/2013 08:37 AM, Lubomir Rintel wrote:
> On Fri, 2013-03-22 at 20:44 -0600, Stephen Warren wrote:
>
> Thank you for your response!
>
>> On 03/22/2013 06:55 AM, Lubomir Rintel wrote:
>>> Signed-off-by: Lubomir Rintel <lkundrak at v3.sk>
>>
>> A commit description would be useful.
>>
>>> arch/arm/boot/dts/bcm2835.dtsi | 5 +
>>> arch/arm/configs/bcm2835_defconfig | 3 +-
>>> drivers/char/hw_random/Kconfig | 12 +++
>>> drivers/char/hw_random/Makefile | 1 +
>>> drivers/char/hw_random/bcm2835-rng.c | 137 ++++++++++++++++++++++++++++++++++
>>
>> This should be split into 3 separate patches: (1) The driver itself, (2)
>> the change to bcm2835.dtsi, and (3) the change to bcm2835_defconfig.
>>
>> Since you're adding a new device to device tree for the first time, you
>> should write a binding document for it; most likely
>> Documentation/devicetree/bindings/rng/brcm,bcm2835.txt (or perhaps
>> /random/ rather than /rng/?)
>
> Okay. I'm tempted to stick to "rng" instead of "random" as it seems more
> consistent to me, but I don't have a strong reason to back it with. What would
> be a good reason for using "random"?

I figured that "random" might be more meaningful/understandable for some
people. It's not a big deal either way though.

2013-03-27 02:55:43

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v2] bcm2835: Add Broadcom BCM2835 RNG to the device tree

On 03/24/2013 08:31 AM, Lubomir Rintel wrote:
> This adds a device tree binding for random number generator present on Broadcom
> BCM2835 SoC, used in Raspberry Pi and Roku 2 devices.
>
> Signed-off-by: Lubomir Rintel <[email protected]>
> Cc: Stephen Warren <[email protected]>
> Cc: [email protected]
> ---
> Changes for v2:
> - Split out from the driver changeset
> - Added documentation
>
> .../devicetree/bindings/rng/brcm,bcm2835.txt | 13 +++++++++++++
> arch/arm/boot/dts/bcm2835.dtsi | 5 +++++
> 2 files changed, 18 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/rng/brcm,bcm2835.txt

I think it's more typical to include the binding document with the
driver patch, so that one patch both defines and implements the binding.
A separate patch then instantiates the binding (i.e. adds entries to *.dts).

Patches that create new DT bindings should be posted to
[email protected], although this one is so simple that
I doubt it will generate any discussion.

Patches that affect ARM files should be posted to
[email protected]. I typically post there instead of
the main linux-kernel@ mailing list.

I assume you're going to repost this anyway once you've addressed the
authorship issue, so you'll have an opportunity to correct all this.

The actual content of this patch seems fine.

2013-03-27 03:00:56

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v2] hw_random: Add Broadcom BCM2835 RNG driver

On 03/24/2013 08:39 AM, Lubomir Rintel wrote:
> This adds a driver for random number generator present on Broadcom BCM2835 SoC,
> used in Raspberry Pi and Roku 2 devices.

I think this looks OK from a quick glance aside from the authorship issue.

This email wasn't Cd'd to Herbert Xu, who is listed as a co-maintainer
of drivers/char/hw_random/, and looks to be more active in applying
hw_random patches than Matt. (Or, I can take this patch through the
bcm2835 ARM tree if it's ack'd by Matt or Herbert)

2013-03-27 03:20:36

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v2] hw_random: Add Broadcom BCM2835 RNG driver

On 03/24/2013 08:39 AM, Lubomir Rintel wrote:
> This adds a driver for random number generator present on Broadcom BCM2835 SoC,
> used in Raspberry Pi and Roku 2 devices.

This, coupled with the other two patches,
Tested-by: Stephen Warren <[email protected]>

2013-03-28 06:12:33

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH] bcm2835: Add Broadcom BCM2835 RNG to the device tree

This adds a device tree binding for random number generator present on Broadcom
BCM2835 SoC, used in Raspberry Pi and Roku 2 devices.

Signed-off-by: Lubomir Rintel <[email protected]>
Tested-by: Stephen Warren <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
---
Changes for v2:
- Split out from the driver changeset
- Added documentation

Changes for v3:
- Moved documentation away to the driver commit

arch/arm/boot/dts/bcm2835.dtsi | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/bcm2835.dtsi b/arch/arm/boot/dts/bcm2835.dtsi
index 7e0481e..dc22336 100644
--- a/arch/arm/boot/dts/bcm2835.dtsi
+++ b/arch/arm/boot/dts/bcm2835.dtsi
@@ -34,6 +34,11 @@
reg = <0x7e100000 0x28>;
};

+ rng {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+ };
+
uart@20201000 {
compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
reg = <0x7e201000 0x1000>;
--
1.7.1

2013-03-28 06:15:33

by Lubomir Rintel

[permalink] [raw]
Subject: Re: [PATCH] hw_random: Add Broadcom BCM2835 RNG Driver

On Fri, 2013-03-22 at 20:44 -0600, Stephen Warren wrote:
> On 03/22/2013 06:55 AM, Lubomir Rintel wrote:
> > Signed-off-by: Lubomir Rintel <[email protected]>
>
> A commit description would be useful.
>
> > arch/arm/boot/dts/bcm2835.dtsi | 5 +
> > arch/arm/configs/bcm2835_defconfig | 3 +-
> > drivers/char/hw_random/Kconfig | 12 +++
> > drivers/char/hw_random/Makefile | 1 +
> > drivers/char/hw_random/bcm2835-rng.c | 137 ++++++++++++++++++++++++++++++++++
>
> This should be split into 3 separate patches: (1) The driver itself, (2)
> the change to bcm2835.dtsi, and (3) the change to bcm2835_defconfig.
>
> Since you're adding a new device to device tree for the first time, you
> should write a binding document for it; most likely
> Documentation/devicetree/bindings/rng/brcm,bcm2835.txt (or perhaps
> /random/ rather than /rng/?)
>
> Is this driver based on the downstream Raspberry Pi kernel's driver? If
> so, some mention of that fact would be appropriate in the commit
> description, or even the git author field. I note that in the downstream
> kernel, the commit which adds the RNG driver isn't signed off at all.
> This probably means you need to get Dom to add his signed-off-by line
> for that commit before basing your work on it. See
> Documentation/SubmittingPatches for more details.

Got this message, will follow up with updated patch:

On Wed, 2013-03-27 at 18:22 +0000, popcornmix wrote:
On Wed, Mar 27, 2013 at 4:55 PM, Lubomir Rintel <[email protected]> wrote:
> > Hi!
> >
> > I'm currently in the process of mainlining the drivers from
Raspberry Pi
> > tree. I was asked for a signoff for the random number generator. It
> > seems to have been commit by you in the downstream tree, I'm
wondering
> > if you could help me, and respond with a Signed-off-by tag if the
code
> > comes from you, or point me to someone else?
> >
> > commit e95a8204d7f8fc4f38900c99080103254c3cef11
> > Author: popcornmix <[email protected]>
> > Date: Wed Jan 30 11:44:26 2013 +0000
> >
> > Add hwrng (hardware random number generator) driver
> >
> > Thank you!
> > --
> > Lubomir Rintel <[email protected]>
> >
>
> Sorry, I'm not up to speed with exactly what constitutes a sign off.
> I did write the original hw-rng driver, and give my permission for it
> to be upstreamed.
> Is this sufficient?
> Signed-off-by: Dom Cobley <[email protected]>
> Signed-off-by: Dom Cobley <[email protected]>
> Signed-off-by: popcornmix <[email protected]>
>
> (not sure which is more suitable - they are all me).

--
Lubomir Rintel (ext. #7715)
GoodData Code Feng Shui Critic

2013-03-28 06:19:49

by Lubomir Rintel

[permalink] [raw]
Subject: [PATCH v3] hw_random: Add Broadcom BCM2835 RNG driver

This adds a driver for random number generator present on Broadcom BCM2835 SoC,
used in Raspberry Pi and Roku 2 devices.

Signed-off-by: Dom Cobley <[email protected]>
Signed-off-by: Lubomir Rintel <[email protected]>
Tested-by: Stephen Warren <[email protected]>
Cc: Herbert Xu <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: Matt Mackall <[email protected]>
Cc: [email protected]
---
Changes for v2:
- Device tree and defconfig changes split out
- Licence changed from GPLv2+BSD to GPLv2 only
- Style fixes

Changes for v3:
- Device tree binding documentation added

.../devicetree/bindings/rng/brcm,bcm2835.txt | 13 +++
drivers/char/hw_random/Kconfig | 12 ++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/bcm2835-rng.c | 113 ++++++++++++++++++++
4 files changed, 139 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/rng/brcm,bcm2835.txt
create mode 100644 drivers/char/hw_random/bcm2835-rng.c

diff --git a/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt
new file mode 100644
index 0000000..07ccdaa
--- /dev/null
+++ b/Documentation/devicetree/bindings/rng/brcm,bcm2835.txt
@@ -0,0 +1,13 @@
+BCM2835 Random number generator
+
+Required properties:
+
+- compatible : should be "brcm,bcm2835-rng"
+- reg : Specifies base physical address and size of the registers.
+
+Example:
+
+rng {
+ compatible = "brcm,bcm2835-rng";
+ reg = <0x7e104000 0x10>;
+};
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index c5a0262..2f9dbf7 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -86,6 +86,18 @@ config HW_RANDOM_BCM63XX

If unusure, say Y.

+config HW_RANDOM_BCM2835
+ tristate "Broadcom BCM2835 Random Number Generator support"
+ depends on HW_RANDOM && ARCH_BCM2835
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on the Broadcom BCM2835 SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bcm2835-rng
+
+ If unsure, say Y.

config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 1fd7eec..bed467c 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
+obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c
new file mode 100644
index 0000000..eb7f147
--- /dev/null
+++ b/drivers/char/hw_random/bcm2835-rng.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2010-2012 Broadcom. All rights reserved.
+ * Copyright (c) 2013 Lubomir Rintel
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License ("GPL")
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/hw_random.h>
+#include <linux/init.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/platform_device.h>
+#include <linux/printk.h>
+
+#define RNG_CTRL 0x0
+#define RNG_STATUS 0x4
+#define RNG_DATA 0x8
+
+/* enable rng */
+#define RNG_RBGEN 0x1
+
+/* the initial numbers generated are "less random" so will be discarded */
+#define RNG_WARMUP_COUNT 0x40000
+
+static int bcm2835_rng_read(struct hwrng *rng, void *buf, size_t max,
+ bool wait)
+{
+ void __iomem *rng_base = (void __iomem *)rng->priv;
+
+ while ((__raw_readl(rng_base + RNG_STATUS) >> 24) == 0) {
+ if (!wait)
+ return 0;
+ cpu_relax();
+ }
+
+ *(u32 *)buf = __raw_readl(rng_base + RNG_DATA);
+ return sizeof(u32);
+}
+
+static struct hwrng bcm2835_rng_ops = {
+ .name = "bcm2835",
+ .read = bcm2835_rng_read,
+};
+
+static int bcm2835_rng_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ void __iomem *rng_base;
+ int err;
+
+ /* map peripheral */
+ rng_base = of_iomap(np, 0);
+ if (!rng_base) {
+ dev_err(dev, "failed to remap rng regs");
+ return -ENODEV;
+ }
+ bcm2835_rng_ops.priv = (unsigned long)rng_base;
+
+ /* register driver */
+ err = hwrng_register(&bcm2835_rng_ops);
+ if (err) {
+ dev_err(dev, "hwrng registration failed\n");
+ iounmap(rng_base);
+ } else {
+ dev_info(dev, "hwrng registered\n");
+
+ /* set warm-up count & enable */
+ __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS);
+ __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL);
+ }
+ return err;
+}
+
+static int bcm2835_rng_remove(struct platform_device *pdev)
+{
+ void __iomem *rng_base = (void __iomem *)bcm2835_rng_ops.priv;
+
+ /* disable rng hardware */
+ __raw_writel(0, rng_base + RNG_CTRL);
+
+ /* unregister driver */
+ hwrng_unregister(&bcm2835_rng_ops);
+ iounmap(rng_base);
+
+ return 0;
+}
+
+static const struct of_device_id bcm2835_rng_of_match[] = {
+ { .compatible = "brcm,bcm2835-rng", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, bcm2835_rng_of_match);
+
+static struct platform_driver bcm2835_rng_driver = {
+ .driver = {
+ .name = "bcm2835-rng",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm2835_rng_of_match,
+ },
+ .probe = bcm2835_rng_probe,
+ .remove = bcm2835_rng_remove,
+};
+module_platform_driver(bcm2835_rng_driver);
+
+MODULE_AUTHOR("Lubomir Rintel <[email protected]>");
+MODULE_DESCRIPTION("BCM2835 Random Number Generator (RNG) driver");
+MODULE_LICENSE("GPLv2");
--
1.7.1

2013-04-02 02:38:47

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH] bcm2835: Add Broadcom BCM2835 RNG to the device tree

On 03/28/2013 12:12 AM, Lubomir Rintel wrote:
> This adds a device tree binding for random number generator present on Broadcom
> BCM2835 SoC, used in Raspberry Pi and Roku 2 devices.

FYI, I intend to apply this patch to the bcm2835 tree whenever the RNG
driver itself is applied to the hw_random tree. If you could ping me
when that happens to jog my memory, that'd be great. Thanks.

2013-04-03 01:54:30

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH v3] hw_random: Add Broadcom BCM2835 RNG driver

On Thu, Mar 28, 2013 at 07:19:38AM +0100, Lubomir Rintel wrote:
> This adds a driver for random number generator present on Broadcom BCM2835 SoC,
> used in Raspberry Pi and Roku 2 devices.

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

2013-04-03 06:28:30

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH v2] arm: Add Broadcom BCM2835 RNG driver to bcm2835_defconfig

On 03/24/2013 08:41 AM, Lubomir Rintel wrote:
> This enables a driver for random number generator present on Broadcom BCM2835 SoC,
> used in Raspberry Pi and Roku 2 devices.

Squashed into bcm2835's for-3.10/defconfig branch.

(Lubomir: defconfig updates get squashed to avoid too many patches
churning that file and causing annoyance)

2013-04-03 06:28:29

by Stephen Warren

[permalink] [raw]
Subject: Re: [PATCH] bcm2835: Add Broadcom BCM2835 RNG to the device tree

On 03/28/2013 12:12 AM, Lubomir Rintel wrote:
> This adds a device tree binding for random number generator present on Broadcom
> BCM2835 SoC, used in Raspberry Pi and Roku 2 devices.

Applied to bcm2835's for-3.10/dt tree, with some slight fixups to the
patch subject and description word-wrapping.