Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-03-02 Thread Scott Branden

Hi Dmitry,

Looking at the driver based on your comments it is following models of 
older hwrng drivers.  I will work on cleaning up based on your comments 
as well.


On 15-02-25 10:43 AM, Dmitry Torokhov wrote:

Hi Scott,

On Wed, Feb 25, 2015 at 10:16:24AM -0800, Scott Branden wrote:

This adds a driver for random number generator present on Broadcom
IPROC devices.

Reviewed-by: Ray Jui 
Signed-off-by: Scott Branden 
---
  drivers/char/hw_random/Kconfig|  13 ++
  drivers/char/hw_random/Makefile   |   1 +
  drivers/char/hw_random/iproc-rng200.c | 239 ++
  3 files changed, 253 insertions(+)
  create mode 100644 drivers/char/hw_random/iproc-rng200.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index de57b38..f48cf11 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835

  If unsure, say Y.

+config HW_RANDOM_IPROC_RNG200
+   tristate "Broadcom iProc RNG200 support"
+   depends on ARCH_BCM_IPROC
+   default HW_RANDOM
+   ---help---
+ This driver provides kernel-side support for the RNG200
+ hardware found on the Broadcom iProc SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called iproc-rng200
+
+ If unsure, say Y.
+
  config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on X86_32 && PCI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 0b4cd57..055bb01 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-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
+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
diff --git a/drivers/char/hw_random/iproc-rng200.c 
b/drivers/char/hw_random/iproc-rng200.c
new file mode 100644
index 000..4643aa9
--- /dev/null
+++ b/drivers/char/hw_random/iproc-rng200.c
@@ -0,0 +1,239 @@
+/*
+* Copyright (C) 2014 Broadcom Corporation
+*
+* This program 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 version 2.
+*
+* This program is distributed "as is" WITHOUT ANY WARRANTY of any
+* kind, whether express or implied; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*/
+/*
+ * DESCRIPTION: The Broadcom iProc RNG200 Driver
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+/* Registers */
+#define RNG_CTRL_OFFSET0x00
+#define RNG_CTRL_RNG_RBGEN_MASK0x1FFF
+#define RNG_CTRL_RNG_RBGEN_ENABLE  0x0001
+#define RNG_CTRL_RNG_RBGEN_DISABLE 0x
+
+#define RNG_SOFT_RESET_OFFSET  0x04
+#define RNG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001
+#define RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE   0x0001
+#define RNG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x
+
+#define RBG_SOFT_RESET_OFFSET  0x08
+#define RBG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001
+#define RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE   0x0001
+#define RBG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x
+
+#define RNG_INT_STATUS_OFFSET  0x18
+#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK0x8000
+#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK0x0002
+#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK  0x0020
+#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK   0x0001
+
+#define RNG_FIFO_DATA_OFFSET   0x20
+
+#define RNG_FIFO_COUNT_OFFSET  0x24
+#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x00FF
+
+static void iproc_rng200_restart(void __iomem *rng_base)
+{
+   uint32_t val;
+
+   /* Disable RBG */
+   val = ioread32(rng_base + RNG_CTRL_OFFSET);
+   val &= ~RNG_CTRL_RNG_RBGEN_MASK;
+   val |= RNG_CTRL_RNG_RBGEN_DISABLE;
+   iowrite32(val, rng_base + RNG_CTRL_OFFSET);
+
+   /* Clear all interrupt status */
+   iowrite32(0xUL, rng_base + RNG_INT_STATUS_OFFSET);
+
+   /* Reset RNG and RBG */
+   val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET);
+   val &= ~RBG_SOFT_RESET_RNG_SOFT_RESET_MASK;
+   val |= RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE;
+   iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET);
+
+   val = ioread32(rng_base + RNG_SOFT_RESET_

Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-03-02 Thread Scott Branden

Hi Arnd,

Thanks for the suggested change.

On 15-02-28 11:31 AM, Arnd Bergmann wrote:

On Saturday 28 February 2015 08:01:11 Scott Branden wrote:

The udelay(10) that the other drivers have seems about appropriate then,
and we can independently think of a way to refine the interface.
Please add a comment that explains the rate. Also, is there some kind
of FIFO present in the hwrng device? If it can store close to 1ms work
of data (1000 bits), you can just use an msleep(1) to wait for the
pool to recover.

FIFO is 512 bits.  I will look as to whether we can live with 1/2
throughput.


In that case, I think usleep_range(min(len * 8, 500), 500)) would be
a good compromise: it waits at most until the fifo is full, but might
return earlier if enough bits are available to fulfill the request.

OK, will change in next version.


Arnd



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-28 Thread Arnd Bergmann
On Saturday 28 February 2015 08:01:11 Scott Branden wrote:
> > The udelay(10) that the other drivers have seems about appropriate then,
> > and we can independently think of a way to refine the interface.
> > Please add a comment that explains the rate. Also, is there some kind
> > of FIFO present in the hwrng device? If it can store close to 1ms work
> > of data (1000 bits), you can just use an msleep(1) to wait for the
> > pool to recover.
> FIFO is 512 bits.  I will look as to whether we can live with 1/2 
> throughput.

In that case, I think usleep_range(min(len * 8, 500), 500)) would be
a good compromise: it waits at most until the fifo is full, but might
return earlier if enough bits are available to fulfill the request.

Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-28 Thread Scott Branden

On 15-02-27 01:14 AM, Arnd Bergmann wrote:

On Thursday 26 February 2015 14:26:02 Scott Branden wrote:

On 15-02-26 12:15 PM, Arnd Bergmann wrote:

On 15-02-25 11:17 AM, Arnd Bergmann wrote:

On Wednesday 25 February 2015 10:16:24 Scott Branden wrote:

This code was following examples of other open source drivers - bcm2835
and exynos both use cpu_relax.  I'll have to look into this more to
understand.



The majority of the driver apparently use udelay(10) to wait, which is
not much better but at least consistent. The cpu_relax() call probably
gives better throughput.

I don't understand why none of the drivers actually attempts to
msleep(), but that may be because the delay is much too long.

Can you find out what the expected latency is for new data to
become available on your hardware?

RNG generates at a nominal 1 Mbps.  So to generate 32 bits of data takes
approximately 32 us.


The udelay(10) that the other drivers have seems about appropriate then,
and we can independently think of a way to refine the interface.
Please add a comment that explains the rate. Also, is there some kind
of FIFO present in the hwrng device? If it can store close to 1ms work
of data (1000 bits), you can just use an msleep(1) to wait for the
pool to recover.
FIFO is 512 bits.  I will look as to whether we can live with 1/2 
throughput.


Another option would be to use usleep_range() with the exact amount
of time to wait for, the lower bound being the minimum number of
bytes asked for and the fifo size, the upper bound being the fifo
size.

Arnd



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-27 Thread Arnd Bergmann
On Thursday 26 February 2015 14:26:02 Scott Branden wrote:
> On 15-02-26 12:15 PM, Arnd Bergmann wrote:
> >> On 15-02-25 11:17 AM, Arnd Bergmann wrote:
> >>> On Wednesday 25 February 2015 10:16:24 Scott Branden wrote:
> >> This code was following examples of other open source drivers - bcm2835
> >> and exynos both use cpu_relax.  I'll have to look into this more to
> >> understand.
> >>
> >
> > The majority of the driver apparently use udelay(10) to wait, which is
> > not much better but at least consistent. The cpu_relax() call probably
> > gives better throughput.
> >
> > I don't understand why none of the drivers actually attempts to
> > msleep(), but that may be because the delay is much too long.
> >
> > Can you find out what the expected latency is for new data to
> > become available on your hardware?
> RNG generates at a nominal 1 Mbps.  So to generate 32 bits of data takes
> approximately 32 us.

The udelay(10) that the other drivers have seems about appropriate then,
and we can independently think of a way to refine the interface.
Please add a comment that explains the rate. Also, is there some kind
of FIFO present in the hwrng device? If it can store close to 1ms work
of data (1000 bits), you can just use an msleep(1) to wait for the
pool to recover.

Another option would be to use usleep_range() with the exact amount
of time to wait for, the lower bound being the minimum number of
bytes asked for and the fifo size, the upper bound being the fifo
size.

Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-26 Thread Scott Branden

Hi Arnd,

Latency is 32 us for 32bits of data - commented inline.  What delay call 
do you recommend in this case?


On 15-02-26 12:15 PM, Arnd Bergmann wrote:

On Thursday 26 February 2015 11:37:20 Scott Branden wrote:

Response inline.

On 15-02-25 11:17 AM, Arnd Bergmann wrote:

On Wednesday 25 February 2015 10:16:24 Scott Branden wrote:

This adds a driver for random number generator present on Broadcom
IPROC devices.

Reviewed-by: Ray Jui 
Signed-off-by: Scott Branden 


The driver looks reasonable overall, I have just one question about
something that sticks out:


+while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) {

...

+
+/* Are there any random numbers available? */
+if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) &
+RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) {

...

+} else {
+if (!wait)
+/* Cannot wait, return immediately */
+return max - num_remaining;
+
+/* Can wait, give others chance to run */
+cpu_relax();
+}
+}
+


It looks like you do a busy-loop around cpu_relax here if asked to wait.
Is this intentional? I would normally expect either cond_resched() or
some msleep() instead.


This code was following examples of other open source drivers - bcm2835
and exynos both use cpu_relax.  I'll have to look into this more to
understand.



The majority of the driver apparently use udelay(10) to wait, which is
not much better but at least consistent. The cpu_relax() call probably
gives better throughput.

I don't understand why none of the drivers actually attempts to
msleep(), but that may be because the delay is much too long.

Can you find out what the expected latency is for new data to
become available on your hardware?

RNG generates at a nominal 1 Mbps.  So to generate 32 bits of data takes
approximately 32 us.



Arnd



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-26 Thread Arnd Bergmann
On Thursday 26 February 2015 11:37:20 Scott Branden wrote:
> Response inline.
> 
> On 15-02-25 11:17 AM, Arnd Bergmann wrote:
> > On Wednesday 25 February 2015 10:16:24 Scott Branden wrote:
> >> This adds a driver for random number generator present on Broadcom
> >> IPROC devices.
> >>
> >> Reviewed-by: Ray Jui 
> >> Signed-off-by: Scott Branden 
> >
> > The driver looks reasonable overall, I have just one question about
> > something that sticks out:
> >
> >> +while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) {
> > ...
> >> +
> >> +/* Are there any random numbers available? */
> >> +if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) &
> >> +RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) {
> > ...
> >> +} else {
> >> +if (!wait)
> >> +/* Cannot wait, return immediately */
> >> +return max - num_remaining;
> >> +
> >> +/* Can wait, give others chance to run */
> >> +cpu_relax();
> >> +}
> >> +}
> >> +
> >
> > It looks like you do a busy-loop around cpu_relax here if asked to wait.
> > Is this intentional? I would normally expect either cond_resched() or
> > some msleep() instead.
> 
> This code was following examples of other open source drivers - bcm2835 
> and exynos both use cpu_relax.  I'll have to look into this more to 
> understand.
> 

The majority of the driver apparently use udelay(10) to wait, which is
not much better but at least consistent. The cpu_relax() call probably
gives better throughput.

I don't understand why none of the drivers actually attempts to
msleep(), but that may be because the delay is much too long.

Can you find out what the expected latency is for new data to
become available on your hardware?

Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-26 Thread Scott Branden

Response inline.

On 15-02-25 11:17 AM, Arnd Bergmann wrote:

On Wednesday 25 February 2015 10:16:24 Scott Branden wrote:

This adds a driver for random number generator present on Broadcom
IPROC devices.

Reviewed-by: Ray Jui 
Signed-off-by: Scott Branden 


The driver looks reasonable overall, I have just one question about
something that sticks out:


+   while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) {

...

+
+   /* Are there any random numbers available? */
+   if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) &
+   RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) {

...

+   } else {
+   if (!wait)
+   /* Cannot wait, return immediately */
+   return max - num_remaining;
+
+   /* Can wait, give others chance to run */
+   cpu_relax();
+   }
+   }
+


It looks like you do a busy-loop around cpu_relax here if asked to wait.
Is this intentional? I would normally expect either cond_resched() or
some msleep() instead.


This code was following examples of other open source drivers - bcm2835 
and exynos both use cpu_relax.  I'll have to look into this more to 
understand.




Arnd



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-25 Thread Arnd Bergmann
On Wednesday 25 February 2015 10:16:24 Scott Branden wrote:
> This adds a driver for random number generator present on Broadcom
> IPROC devices.
> 
> Reviewed-by: Ray Jui 
> Signed-off-by: Scott Branden 

The driver looks reasonable overall, I have just one question about
something that sticks out:

> + while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) {
...
> +
> + /* Are there any random numbers available? */
> + if ((ioread32(rng_base + RNG_FIFO_COUNT_OFFSET) &
> + RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) {
...
> + } else {
> + if (!wait)
> + /* Cannot wait, return immediately */
> + return max - num_remaining;
> +
> + /* Can wait, give others chance to run */
> + cpu_relax();
> + }
> + }
> +

It looks like you do a busy-loop around cpu_relax here if asked to wait.
Is this intentional? I would normally expect either cond_resched() or
some msleep() instead.

Arnd
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-25 Thread Dmitry Torokhov
Hi Scott,

On Wed, Feb 25, 2015 at 10:16:24AM -0800, Scott Branden wrote:
> This adds a driver for random number generator present on Broadcom
> IPROC devices.
> 
> Reviewed-by: Ray Jui 
> Signed-off-by: Scott Branden 
> ---
>  drivers/char/hw_random/Kconfig|  13 ++
>  drivers/char/hw_random/Makefile   |   1 +
>  drivers/char/hw_random/iproc-rng200.c | 239 
> ++
>  3 files changed, 253 insertions(+)
>  create mode 100644 drivers/char/hw_random/iproc-rng200.c
> 
> diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
> index de57b38..f48cf11 100644
> --- a/drivers/char/hw_random/Kconfig
> +++ b/drivers/char/hw_random/Kconfig
> @@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835
>  
> If unsure, say Y.
>  
> +config HW_RANDOM_IPROC_RNG200
> + tristate "Broadcom iProc RNG200 support"
> + depends on ARCH_BCM_IPROC
> + default HW_RANDOM
> + ---help---
> +   This driver provides kernel-side support for the RNG200
> +   hardware found on the Broadcom iProc SoCs.
> +
> +   To compile this driver as a module, choose M here: the
> +   module will be called iproc-rng200
> +
> +   If unsure, say Y.
> +
>  config HW_RANDOM_GEODE
>   tristate "AMD Geode HW Random Number Generator support"
>   depends on X86_32 && PCI
> diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
> index 0b4cd57..055bb01 100644
> --- a/drivers/char/hw_random/Makefile
> +++ b/drivers/char/hw_random/Makefile
> @@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-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
> +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
> diff --git a/drivers/char/hw_random/iproc-rng200.c 
> b/drivers/char/hw_random/iproc-rng200.c
> new file mode 100644
> index 000..4643aa9
> --- /dev/null
> +++ b/drivers/char/hw_random/iproc-rng200.c
> @@ -0,0 +1,239 @@
> +/*
> +* Copyright (C) 2014 Broadcom Corporation
> +*
> +* This program 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 version 2.
> +*
> +* This program is distributed "as is" WITHOUT ANY WARRANTY of any
> +* kind, whether express or implied; without even the implied warranty
> +* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +* GNU General Public License for more details.
> +*/
> +/*
> + * DESCRIPTION: The Broadcom iProc RNG200 Driver
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +
> +/* Registers */
> +#define RNG_CTRL_OFFSET  0x00
> +#define RNG_CTRL_RNG_RBGEN_MASK  0x1FFF
> +#define RNG_CTRL_RNG_RBGEN_ENABLE0x0001
> +#define RNG_CTRL_RNG_RBGEN_DISABLE   0x
> +
> +#define RNG_SOFT_RESET_OFFSET0x04
> +#define RNG_SOFT_RESET_RNG_SOFT_RESET_MASK   0x0001
> +#define RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001
> +#define RNG_SOFT_RESET_RNG_SOFT_RESET_CLEAR  0x
> +
> +#define RBG_SOFT_RESET_OFFSET0x08
> +#define RBG_SOFT_RESET_RNG_SOFT_RESET_MASK   0x0001
> +#define RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE 0x0001
> +#define RBG_SOFT_RESET_RNG_SOFT_RESET_CLEAR  0x
> +
> +#define RNG_INT_STATUS_OFFSET0x18
> +#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK  0x8000
> +#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK  0x0002
> +#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK0x0020
> +#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK 0x0001
> +
> +#define RNG_FIFO_DATA_OFFSET 0x20
> +
> +#define RNG_FIFO_COUNT_OFFSET0x24
> +#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK   0x00FF
> +
> +static void iproc_rng200_restart(void __iomem *rng_base)
> +{
> + uint32_t val;
> +
> + /* Disable RBG */
> + val = ioread32(rng_base + RNG_CTRL_OFFSET);
> + val &= ~RNG_CTRL_RNG_RBGEN_MASK;
> + val |= RNG_CTRL_RNG_RBGEN_DISABLE;
> + iowrite32(val, rng_base + RNG_CTRL_OFFSET);
> +
> + /* Clear all interrupt status */
> + iowrite32(0xUL, rng_base + RNG_INT_STATUS_OFFSET);
> +
> + /* Reset RNG and RBG */
> + val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET);
> + val &= ~RBG_SOFT_RESET_RNG_SOFT_RESET_MASK;
> + val |= RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE;
> + iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET);
> +
> + val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET);
> + val &= ~RN

[PATCH v2 2/2] hwrng: iproc-rng200 - Add Broadcom IPROC RNG driver

2015-02-25 Thread Scott Branden
This adds a driver for random number generator present on Broadcom
IPROC devices.

Reviewed-by: Ray Jui 
Signed-off-by: Scott Branden 
---
 drivers/char/hw_random/Kconfig|  13 ++
 drivers/char/hw_random/Makefile   |   1 +
 drivers/char/hw_random/iproc-rng200.c | 239 ++
 3 files changed, 253 insertions(+)
 create mode 100644 drivers/char/hw_random/iproc-rng200.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index de57b38..f48cf11 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -101,6 +101,19 @@ config HW_RANDOM_BCM2835
 
  If unsure, say Y.
 
+config HW_RANDOM_IPROC_RNG200
+   tristate "Broadcom iProc RNG200 support"
+   depends on ARCH_BCM_IPROC
+   default HW_RANDOM
+   ---help---
+ This driver provides kernel-side support for the RNG200
+ hardware found on the Broadcom iProc SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called iproc-rng200
+
+ If unsure, say Y.
+
 config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on X86_32 && PCI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 0b4cd57..055bb01 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -28,5 +28,6 @@ obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-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
+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
diff --git a/drivers/char/hw_random/iproc-rng200.c 
b/drivers/char/hw_random/iproc-rng200.c
new file mode 100644
index 000..4643aa9
--- /dev/null
+++ b/drivers/char/hw_random/iproc-rng200.c
@@ -0,0 +1,239 @@
+/*
+* Copyright (C) 2014 Broadcom Corporation
+*
+* This program 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 version 2.
+*
+* This program is distributed "as is" WITHOUT ANY WARRANTY of any
+* kind, whether express or implied; without even the implied warranty
+* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*/
+/*
+ * DESCRIPTION: The Broadcom iProc RNG200 Driver
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+/* Registers */
+#define RNG_CTRL_OFFSET0x00
+#define RNG_CTRL_RNG_RBGEN_MASK0x1FFF
+#define RNG_CTRL_RNG_RBGEN_ENABLE  0x0001
+#define RNG_CTRL_RNG_RBGEN_DISABLE 0x
+
+#define RNG_SOFT_RESET_OFFSET  0x04
+#define RNG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001
+#define RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE   0x0001
+#define RNG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x
+
+#define RBG_SOFT_RESET_OFFSET  0x08
+#define RBG_SOFT_RESET_RNG_SOFT_RESET_MASK 0x0001
+#define RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE   0x0001
+#define RBG_SOFT_RESET_RNG_SOFT_RESET_CLEAR0x
+
+#define RNG_INT_STATUS_OFFSET  0x18
+#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK0x8000
+#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK0x0002
+#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK  0x0020
+#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK   0x0001
+
+#define RNG_FIFO_DATA_OFFSET   0x20
+
+#define RNG_FIFO_COUNT_OFFSET  0x24
+#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK 0x00FF
+
+static void iproc_rng200_restart(void __iomem *rng_base)
+{
+   uint32_t val;
+
+   /* Disable RBG */
+   val = ioread32(rng_base + RNG_CTRL_OFFSET);
+   val &= ~RNG_CTRL_RNG_RBGEN_MASK;
+   val |= RNG_CTRL_RNG_RBGEN_DISABLE;
+   iowrite32(val, rng_base + RNG_CTRL_OFFSET);
+
+   /* Clear all interrupt status */
+   iowrite32(0xUL, rng_base + RNG_INT_STATUS_OFFSET);
+
+   /* Reset RNG and RBG */
+   val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET);
+   val &= ~RBG_SOFT_RESET_RNG_SOFT_RESET_MASK;
+   val |= RBG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE;
+   iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET);
+
+   val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET);
+   val &= ~RNG_SOFT_RESET_RNG_SOFT_RESET_MASK;
+   val |= RNG_SOFT_RESET_RNG_SOFT_RESET_ACTIVE;
+   iowrite32(val, rng_base + RNG_SOFT_RESET_OFFSET);
+
+   val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET);
+   val &= ~RNG_SOFT_RESET_RNG_SOFT_RESET_MASK;
+   val |= RNG_SOF