--- /dev/null
+From d114a33387472555188f142ed8e98acdb8181c6d Mon Sep 17 00:00:00 2001
+From: Tony Luck <tony.luck@intel.com>
+Date: Fri, 20 Jul 2012 13:15:20 -0700
+Subject: dmi: Feed DMI table to /dev/random driver
+
+From: Tony Luck <tony.luck@intel.com>
+
+commit d114a33387472555188f142ed8e98acdb8181c6d upstream.
+
+Send the entire DMI (SMBIOS) table to the /dev/random driver to
+help seed its pools.
+
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/dmi_scan.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/firmware/dmi_scan.c
++++ b/drivers/firmware/dmi_scan.c
+@@ -6,6 +6,7 @@
+ #include <linux/dmi.h>
+ #include <linux/efi.h>
+ #include <linux/bootmem.h>
++#include <linux/random.h>
+ #include <asm/dmi.h>
+
+ /*
+@@ -111,6 +112,8 @@ static int __init dmi_walk_early(void (*
+
+ dmi_table(buf, dmi_len, dmi_num, decode, NULL);
+
++ add_device_randomness(buf, dmi_len);
++
+ dmi_iounmap(buf, dmi_len);
+ return 0;
+ }
--- /dev/null
+From 330e0a01d54c2b8606c56816f99af6ebc58ec92c Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 4 Jul 2012 11:32:48 -0400
+Subject: MAINTAINERS: Theodore Ts'o is taking over the random driver
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 330e0a01d54c2b8606c56816f99af6ebc58ec92c upstream.
+
+Matt Mackall stepped down as the /dev/random driver maintainer last
+year, so Theodore Ts'o is taking back the /dev/random driver.
+
+Cc: Matt Mackall <mpm@selenic.com>
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ MAINTAINERS | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -5247,7 +5247,7 @@ F: Documentation/blockdev/ramdisk.txt
+ F: drivers/block/brd.c
+
+ RANDOM NUMBER DRIVER
+-M: Matt Mackall <mpm@selenic.com>
++M: Theodore Ts'o" <tytso@mit.edu>
+ S: Maintained
+ F: drivers/char/random.c
+
--- /dev/null
+From 27130f0cc3ab97560384da437e4621fc4e94f21c Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Thu, 5 Jul 2012 20:23:21 +0000
+Subject: mfd: wm831x: Feed the device UUID into device_add_randomness()
+
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+
+commit 27130f0cc3ab97560384da437e4621fc4e94f21c upstream.
+
+wm831x devices contain a unique ID value. Feed this into the newly added
+device_add_randomness() to add some per device seed data to the pool.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mfd/wm831x-otp.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/mfd/wm831x-otp.c
++++ b/drivers/mfd/wm831x-otp.c
+@@ -18,6 +18,7 @@
+ #include <linux/bcd.h>
+ #include <linux/delay.h>
+ #include <linux/mfd/core.h>
++#include <linux/random.h>
+
+ #include <linux/mfd/wm831x/core.h>
+ #include <linux/mfd/wm831x/otp.h>
+@@ -66,6 +67,7 @@ static DEVICE_ATTR(unique_id, 0444, wm83
+
+ int wm831x_otp_init(struct wm831x *wm831x)
+ {
++ char uuid[WM831X_UNIQUE_ID_LEN];
+ int ret;
+
+ ret = device_create_file(wm831x->dev, &dev_attr_unique_id);
+@@ -73,6 +75,12 @@ int wm831x_otp_init(struct wm831x *wm831
+ dev_err(wm831x->dev, "Unique ID attribute not created: %d\n",
+ ret);
+
++ ret = wm831x_unique_id_read(wm831x, uuid);
++ if (ret == 0)
++ add_device_randomness(uuid, sizeof(uuid));
++ else
++ dev_err(wm831x->dev, "Failed to read UUID: %d\n", ret);
++
+ return ret;
+ }
+
--- /dev/null
+From cbc96b7594b5691d61eba2db8b2ea723645be9ca Mon Sep 17 00:00:00 2001
+From: Tony Luck <tony.luck@intel.com>
+Date: Mon, 23 Jul 2012 09:47:57 -0700
+Subject: random: Add comment to random_initialize()
+
+From: Tony Luck <tony.luck@intel.com>
+
+commit cbc96b7594b5691d61eba2db8b2ea723645be9ca upstream.
+
+Many platforms have per-machine instance data (serial numbers,
+asset tags, etc.) squirreled away in areas that are accessed
+during early system bringup. Mixing this data into the random
+pools has a very high value in providing better random data,
+so we should allow (and even encourage) architecture code to
+call add_device_randomness() from the setup_arch() paths.
+
+However, this limits our options for internal structure of
+the random driver since random_initialize() is not called
+until long after setup_arch().
+
+Add a big fat comment to rand_initialize() spelling out
+this requirement.
+
+Suggested-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -1087,6 +1087,16 @@ static void init_std_data(struct entropy
+ mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL);
+ }
+
++/*
++ * Note that setup_arch() may call add_device_randomness()
++ * long before we get here. This allows seeding of the pools
++ * with some platform dependent data very early in the boot
++ * process. But it limits our options here. We must use
++ * statically allocated structures that already have all
++ * initializations complete at compile time. We should also
++ * take care not to overwrite the precious per platform data
++ * we were given.
++ */
+ static int rand_initialize(void)
+ {
+ init_std_data(&input_pool);
--- /dev/null
+From 00ce1db1a634746040ace24c09a4e3a7949a3145 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Wed, 4 Jul 2012 16:19:30 -0400
+Subject: random: add tracepoints for easier debugging and verification
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit 00ce1db1a634746040ace24c09a4e3a7949a3145 upstream.
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 26 ++++++--
+ include/trace/events/random.h | 134 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 156 insertions(+), 4 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -266,6 +266,9 @@
+ #include <asm/irq_regs.h>
+ #include <asm/io.h>
+
++#define CREATE_TRACE_POINTS
++#include <trace/events/random.h>
++
+ /*
+ * Configuration information
+ */
+@@ -478,8 +481,8 @@ static __u32 const twist_table[8] = {
+ * it's cheap to do so and helps slightly in the expected case where
+ * the entropy is concentrated in the low-order bits.
+ */
+-static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+- int nbytes, __u8 out[64])
++static void _mix_pool_bytes(struct entropy_store *r, const void *in,
++ int nbytes, __u8 out[64])
+ {
+ unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
+ int input_rotate;
+@@ -531,13 +534,21 @@ static void __mix_pool_bytes(struct entr
+ ((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
+ }
+
+-static void mix_pool_bytes(struct entropy_store *r, const void *in,
++static void __mix_pool_bytes(struct entropy_store *r, const void *in,
+ int nbytes, __u8 out[64])
+ {
++ trace_mix_pool_bytes_nolock(r->name, nbytes, _RET_IP_);
++ _mix_pool_bytes(r, in, nbytes, out);
++}
++
++static void mix_pool_bytes(struct entropy_store *r, const void *in,
++ int nbytes, __u8 out[64])
++{
+ unsigned long flags;
+
++ trace_mix_pool_bytes(r->name, nbytes, _RET_IP_);
+ spin_lock_irqsave(&r->lock, flags);
+- __mix_pool_bytes(r, in, nbytes, out);
++ _mix_pool_bytes(r, in, nbytes, out);
+ spin_unlock_irqrestore(&r->lock, flags);
+ }
+
+@@ -585,6 +596,7 @@ static void credit_entropy_bits(struct e
+ retry:
+ entropy_count = orig = ACCESS_ONCE(r->entropy_count);
+ entropy_count += nbits;
++
+ if (entropy_count < 0) {
+ DEBUG_ENT("negative entropy/overflow\n");
+ entropy_count = 0;
+@@ -599,6 +611,9 @@ retry:
+ r->initialized = 1;
+ }
+
++ trace_credit_entropy_bits(r->name, nbits, entropy_count,
++ r->entropy_total, _RET_IP_);
++
+ /* should we wake readers? */
+ if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
+ wake_up_interruptible(&random_read_wait);
+@@ -971,6 +986,7 @@ static ssize_t extract_entropy(struct en
+ ssize_t ret = 0, i;
+ __u8 tmp[EXTRACT_SIZE];
+
++ trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_);
+ xfer_secondary_pool(r, nbytes);
+ nbytes = account(r, nbytes, min, reserved);
+
+@@ -1005,6 +1021,7 @@ static ssize_t extract_entropy_user(stru
+ ssize_t ret = 0, i;
+ __u8 tmp[EXTRACT_SIZE];
+
++ trace_extract_entropy_user(r->name, nbytes, r->entropy_count, _RET_IP_);
+ xfer_secondary_pool(r, nbytes);
+ nbytes = account(r, nbytes, 0, 0);
+
+@@ -1062,6 +1079,7 @@ void get_random_bytes_arch(void *buf, in
+ {
+ char *p = buf;
+
++ trace_get_random_bytes(nbytes, _RET_IP_);
+ while (nbytes) {
+ unsigned long v;
+ int chunk = min(nbytes, (int)sizeof(unsigned long));
+--- /dev/null
++++ b/include/trace/events/random.h
+@@ -0,0 +1,134 @@
++#undef TRACE_SYSTEM
++#define TRACE_SYSTEM random
++
++#if !defined(_TRACE_RANDOM_H) || defined(TRACE_HEADER_MULTI_READ)
++#define _TRACE_RANDOM_H
++
++#include <linux/writeback.h>
++#include <linux/tracepoint.h>
++
++DECLARE_EVENT_CLASS(random__mix_pool_bytes,
++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
++
++ TP_ARGS(pool_name, bytes, IP),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, bytes )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->bytes = bytes;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("%s pool: bytes %d caller %pF",
++ __entry->pool_name, __entry->bytes, (void *)__entry->IP)
++);
++
++DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes,
++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
++
++ TP_ARGS(pool_name, bytes, IP)
++);
++
++DEFINE_EVENT(random__mix_pool_bytes, mix_pool_bytes_nolock,
++ TP_PROTO(const char *pool_name, int bytes, unsigned long IP),
++
++ TP_ARGS(pool_name, bytes, IP)
++);
++
++TRACE_EVENT(credit_entropy_bits,
++ TP_PROTO(const char *pool_name, int bits, int entropy_count,
++ int entropy_total, unsigned long IP),
++
++ TP_ARGS(pool_name, bits, entropy_count, entropy_total, IP),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, bits )
++ __field( int, entropy_count )
++ __field( int, entropy_total )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->bits = bits;
++ __entry->entropy_count = entropy_count;
++ __entry->entropy_total = entropy_total;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("%s pool: bits %d entropy_count %d entropy_total %d "
++ "caller %pF", __entry->pool_name, __entry->bits,
++ __entry->entropy_count, __entry->entropy_total,
++ (void *)__entry->IP)
++);
++
++TRACE_EVENT(get_random_bytes,
++ TP_PROTO(int nbytes, unsigned long IP),
++
++ TP_ARGS(nbytes, IP),
++
++ TP_STRUCT__entry(
++ __field( int, nbytes )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->nbytes = nbytes;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("nbytes %d caller %pF", __entry->nbytes, (void *)__entry->IP)
++);
++
++DECLARE_EVENT_CLASS(random__extract_entropy,
++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
++ unsigned long IP),
++
++ TP_ARGS(pool_name, nbytes, entropy_count, IP),
++
++ TP_STRUCT__entry(
++ __field( const char *, pool_name )
++ __field( int, nbytes )
++ __field( int, entropy_count )
++ __field(unsigned long, IP )
++ ),
++
++ TP_fast_assign(
++ __entry->pool_name = pool_name;
++ __entry->nbytes = nbytes;
++ __entry->entropy_count = entropy_count;
++ __entry->IP = IP;
++ ),
++
++ TP_printk("%s pool: nbytes %d entropy_count %d caller %pF",
++ __entry->pool_name, __entry->nbytes, __entry->entropy_count,
++ (void *)__entry->IP)
++);
++
++
++DEFINE_EVENT(random__extract_entropy, extract_entropy,
++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
++ unsigned long IP),
++
++ TP_ARGS(pool_name, nbytes, entropy_count, IP)
++);
++
++DEFINE_EVENT(random__extract_entropy, extract_entropy_user,
++ TP_PROTO(const char *pool_name, int nbytes, int entropy_count,
++ unsigned long IP),
++
++ TP_ARGS(pool_name, nbytes, entropy_count, IP)
++);
++
++
++
++#endif /* _TRACE_RANDOM_H */
++
++/* This part must be outside protection */
++#include <trace/define_trace.h>
--- /dev/null
+From d2e7c96af1e54b507ae2a6a7dd2baf588417a7e5 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+Date: Fri, 27 Jul 2012 22:26:08 -0400
+Subject: random: mix in architectural randomness in extract_buf()
+
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+
+commit d2e7c96af1e54b507ae2a6a7dd2baf588417a7e5 upstream.
+
+Mix in any architectural randomness in extract_buf() instead of
+xfer_secondary_buf(). This allows us to mix in more architectural
+randomness, and it also makes xfer_secondary_buf() faster, moving a
+tiny bit of additional CPU overhead to process which is extracting the
+randomness.
+
+[ Commit description modified by tytso to remove an extended
+ advertisement for the RDRAND instruction. ]
+
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: DJ Johnston <dj.johnston@intel.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/random.c | 56 ++++++++++++++++++++++++++++----------------------
+ 1 file changed, 32 insertions(+), 24 deletions(-)
+
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -277,6 +277,8 @@
+ #define SEC_XFER_SIZE 512
+ #define EXTRACT_SIZE 10
+
++#define LONGS(x) (((x) + sizeof(unsigned long) - 1)/sizeof(unsigned long))
++
+ /*
+ * The minimum number of bits of entropy before we wake up a read on
+ * /dev/random. Should be enough to do a significant reseed.
+@@ -813,11 +815,7 @@ static ssize_t extract_entropy(struct en
+ */
+ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
+ {
+- union {
+- __u32 tmp[OUTPUT_POOL_WORDS];
+- long hwrand[4];
+- } u;
+- int i;
++ __u32 tmp[OUTPUT_POOL_WORDS];
+
+ if (r->pull && r->entropy_count < nbytes * 8 &&
+ r->entropy_count < r->poolinfo->POOLBITS) {
+@@ -828,23 +826,17 @@ static void xfer_secondary_pool(struct e
+ /* pull at least as many as BYTES as wakeup BITS */
+ bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
+ /* but never more than the buffer size */
+- bytes = min_t(int, bytes, sizeof(u.tmp));
++ bytes = min_t(int, bytes, sizeof(tmp));
+
+ DEBUG_ENT("going to reseed %s with %d bits "
+ "(%d of %d requested)\n",
+ r->name, bytes * 8, nbytes * 8, r->entropy_count);
+
+- bytes = extract_entropy(r->pull, u.tmp, bytes,
++ bytes = extract_entropy(r->pull, tmp, bytes,
+ random_read_wakeup_thresh / 8, rsvd);
+- mix_pool_bytes(r, u.tmp, bytes, NULL);
++ mix_pool_bytes(r, tmp, bytes, NULL);
+ credit_entropy_bits(r, bytes*8);
+ }
+- kmemcheck_mark_initialized(&u.hwrand, sizeof(u.hwrand));
+- for (i = 0; i < 4; i++)
+- if (arch_get_random_long(&u.hwrand[i]))
+- break;
+- if (i)
+- mix_pool_bytes(r, &u.hwrand, sizeof(u.hwrand), 0);
+ }
+
+ /*
+@@ -901,15 +893,19 @@ static size_t account(struct entropy_sto
+ static void extract_buf(struct entropy_store *r, __u8 *out)
+ {
+ int i;
+- __u32 hash[5], workspace[SHA_WORKSPACE_WORDS];
++ union {
++ __u32 w[5];
++ unsigned long l[LONGS(EXTRACT_SIZE)];
++ } hash;
++ __u32 workspace[SHA_WORKSPACE_WORDS];
+ __u8 extract[64];
+ unsigned long flags;
+
+ /* Generate a hash across the pool, 16 words (512 bits) at a time */
+- sha_init(hash);
++ sha_init(hash.w);
+ spin_lock_irqsave(&r->lock, flags);
+ for (i = 0; i < r->poolinfo->poolwords; i += 16)
+- sha_transform(hash, (__u8 *)(r->pool + i), workspace);
++ sha_transform(hash.w, (__u8 *)(r->pool + i), workspace);
+
+ /*
+ * We mix the hash back into the pool to prevent backtracking
+@@ -920,14 +916,14 @@ static void extract_buf(struct entropy_s
+ * brute-forcing the feedback as hard as brute-forcing the
+ * hash.
+ */
+- __mix_pool_bytes(r, hash, sizeof(hash), extract);
++ __mix_pool_bytes(r, hash.w, sizeof(hash.w), extract);
+ spin_unlock_irqrestore(&r->lock, flags);
+
+ /*
+ * To avoid duplicates, we atomically extract a portion of the
+ * pool while mixing, and hash one final time.
+ */
+- sha_transform(hash, extract, workspace);
++ sha_transform(hash.w, extract, workspace);
+ memset(extract, 0, sizeof(extract));
+ memset(workspace, 0, sizeof(workspace));
+
+@@ -936,11 +932,23 @@ static void extract_buf(struct entropy_s
+ * pattern, we fold it in half. Thus, we always feed back
+ * twice as much data as we output.
+ */
+- hash[0] ^= hash[3];
+- hash[1] ^= hash[4];
+- hash[2] ^= rol32(hash[2], 16);
+- memcpy(out, hash, EXTRACT_SIZE);
+- memset(hash, 0, sizeof(hash));
++ hash.w[0] ^= hash.w[3];
++ hash.w[1] ^= hash.w[4];
++ hash.w[2] ^= rol32(hash.w[2], 16);
++
++ /*
++ * If we have a architectural hardware random number
++ * generator, mix that in, too.
++ */
++ for (i = 0; i < LONGS(EXTRACT_SIZE); i++) {
++ unsigned long v;
++ if (!arch_get_random_long(&v))
++ break;
++ hash.l[i] ^= v;
++ }
++
++ memcpy(out, &hash, EXTRACT_SIZE);
++ memset(&hash, 0, sizeof(hash));
+ }
+
+ static ssize_t extract_entropy(struct entropy_store *r, void *buf,
--- /dev/null
+From c5857ccf293968348e5eb4ebedc68074de3dcda6 Mon Sep 17 00:00:00 2001
+From: Theodore Ts'o <tytso@mit.edu>
+Date: Sat, 14 Jul 2012 20:27:52 -0400
+Subject: random: remove rand_initialize_irq()
+
+From: Theodore Ts'o <tytso@mit.edu>
+
+commit c5857ccf293968348e5eb4ebedc68074de3dcda6 upstream.
+
+With the new interrupt sampling system, we are no longer using the
+timer_rand_state structure in the irq descriptor, so we can stop
+initializing it now.
+
+[ Merged in fixes from Sedat to find some last missing references to
+ rand_initialize_irq() ]
+
+Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
+Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/ia64/kernel/irq_ia64.c | 1
+ drivers/char/random.c | 55 --------------------------------------------
+ drivers/mfd/ab3100-core.c | 3 --
+ drivers/mfd/ab3550-core.c | 2 -
+ include/linux/irqdesc.h | 1
+ include/linux/random.h | 2 -
+ kernel/irq/manage.c | 17 -------------
+ 7 files changed, 81 deletions(-)
+
+--- a/arch/ia64/kernel/irq_ia64.c
++++ b/arch/ia64/kernel/irq_ia64.c
+@@ -23,7 +23,6 @@
+ #include <linux/ioport.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/ptrace.h>
+-#include <linux/random.h> /* for rand_initialize_irq() */
+ #include <linux/signal.h>
+ #include <linux/smp.h>
+ #include <linux/threads.h>
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -634,43 +634,6 @@ struct timer_rand_state {
+ unsigned dont_count_entropy:1;
+ };
+
+-#ifndef CONFIG_GENERIC_HARDIRQS
+-
+-static struct timer_rand_state *irq_timer_state[NR_IRQS];
+-
+-static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
+-{
+- return irq_timer_state[irq];
+-}
+-
+-static void set_timer_rand_state(unsigned int irq,
+- struct timer_rand_state *state)
+-{
+- irq_timer_state[irq] = state;
+-}
+-
+-#else
+-
+-static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
+-{
+- struct irq_desc *desc;
+-
+- desc = irq_to_desc(irq);
+-
+- return desc->timer_rand_state;
+-}
+-
+-static void set_timer_rand_state(unsigned int irq,
+- struct timer_rand_state *state)
+-{
+- struct irq_desc *desc;
+-
+- desc = irq_to_desc(irq);
+-
+- desc->timer_rand_state = state;
+-}
+-#endif
+-
+ /*
+ * Add device- or boot-specific data to the input and nonblocking
+ * pools to help initialize them to unique values.
+@@ -1133,24 +1096,6 @@ static int rand_initialize(void)
+ }
+ module_init(rand_initialize);
+
+-void rand_initialize_irq(int irq)
+-{
+- struct timer_rand_state *state;
+-
+- state = get_timer_rand_state(irq);
+-
+- if (state)
+- return;
+-
+- /*
+- * If kzalloc returns null, we just won't use that entropy
+- * source.
+- */
+- state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
+- if (state)
+- set_timer_rand_state(irq, state);
+-}
+-
+ #ifdef CONFIG_BLOCK
+ void rand_initialize_disk(struct gendisk *disk)
+ {
+--- a/drivers/mfd/ab3100-core.c
++++ b/drivers/mfd/ab3100-core.c
+@@ -936,9 +936,6 @@ static int __devinit ab3100_probe(struct
+
+ err = request_threaded_irq(client->irq, NULL, ab3100_irq_handler,
+ IRQF_ONESHOT, "ab3100-core", ab3100);
+- /* This real unpredictable IRQ is of course sampled for entropy */
+- rand_initialize_irq(client->irq);
+-
+ if (err)
+ goto exit_no_irq;
+
+--- a/drivers/mfd/ab3550-core.c
++++ b/drivers/mfd/ab3550-core.c
+@@ -1309,8 +1309,6 @@ static int __init ab3550_probe(struct i2
+
+ err = request_threaded_irq(client->irq, NULL, ab3550_irq_handler,
+ IRQF_ONESHOT, "ab3550-core", ab);
+- /* This real unpredictable IRQ is of course sampled for entropy */
+- rand_initialize_irq(client->irq);
+
+ if (err)
+ goto exit_no_irq;
+--- a/include/linux/irqdesc.h
++++ b/include/linux/irqdesc.h
+@@ -38,7 +38,6 @@ struct timer_rand_state;
+ */
+ struct irq_desc {
+ struct irq_data irq_data;
+- struct timer_rand_state *timer_rand_state;
+ unsigned int __percpu *kstat_irqs;
+ irq_flow_handler_t handle_irq;
+ #ifdef CONFIG_IRQ_PREFLOW_FASTEOI
+--- a/include/linux/random.h
++++ b/include/linux/random.h
+@@ -48,8 +48,6 @@ struct rnd_state {
+
+ #ifdef __KERNEL__
+
+-extern void rand_initialize_irq(int irq);
+-
+ extern void add_device_randomness(const void *, unsigned int);
+ extern void add_input_randomness(unsigned int type, unsigned int code,
+ unsigned int value);
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -886,22 +886,6 @@ __setup_irq(unsigned int irq, struct irq
+
+ if (desc->irq_data.chip == &no_irq_chip)
+ return -ENOSYS;
+- /*
+- * Some drivers like serial.c use request_irq() heavily,
+- * so we have to be careful not to interfere with a
+- * running system.
+- */
+- if (new->flags & IRQF_SAMPLE_RANDOM) {
+- /*
+- * This function might sleep, we want to call it first,
+- * outside of the atomic block.
+- * Yes, this might clear the entropy pool if the wrong
+- * driver is attempted to be loaded, without actually
+- * installing a new handler, but is this really a problem,
+- * only the sysadmin is able to do this.
+- */
+- rand_initialize_irq(irq);
+- }
+
+ /*
+ * Check whether the interrupt nests into another interrupt
+@@ -1325,7 +1309,6 @@ EXPORT_SYMBOL(free_irq);
+ * Flags:
+ *
+ * IRQF_SHARED Interrupt is shared
+- * IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
+ * IRQF_TRIGGER_* Specify active edge(s) or level
+ *
+ */
--- /dev/null
+From 9dccf55f4cb011a7552a8a2749a580662f5ed8ed Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Date: Thu, 5 Jul 2012 20:19:17 +0000
+Subject: rtc: wm831x: Feed the write counter into device_add_randomness()
+
+From: Mark Brown <broonie@opensource.wolfsonmicro.com>
+
+commit 9dccf55f4cb011a7552a8a2749a580662f5ed8ed upstream.
+
+The tamper evident features of the RTC include the "write counter" which
+is a pseudo-random number regenerated whenever we set the RTC. Since this
+value is unpredictable it should provide some useful seeding to the random
+number generator.
+
+Only do this on boot since the goal is to seed the pool rather than add
+useful entropy.
+
+Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/rtc/rtc-wm831x.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
+
+--- a/drivers/rtc/rtc-wm831x.c
++++ b/drivers/rtc/rtc-wm831x.c
+@@ -24,7 +24,7 @@
+ #include <linux/mfd/wm831x/core.h>
+ #include <linux/delay.h>
+ #include <linux/platform_device.h>
+-
++#include <linux/random.h>
+
+ /*
+ * R16416 (0x4020) - RTC Write Counter
+@@ -96,6 +96,26 @@ struct wm831x_rtc {
+ unsigned int alarm_enabled:1;
+ };
+
++static void wm831x_rtc_add_randomness(struct wm831x *wm831x)
++{
++ int ret;
++ u16 reg;
++
++ /*
++ * The write counter contains a pseudo-random number which is
++ * regenerated every time we set the RTC so it should be a
++ * useful per-system source of entropy.
++ */
++ ret = wm831x_reg_read(wm831x, WM831X_RTC_WRITE_COUNTER);
++ if (ret >= 0) {
++ reg = ret;
++ add_device_randomness(®, sizeof(reg));
++ } else {
++ dev_warn(wm831x->dev, "Failed to read RTC write counter: %d\n",
++ ret);
++ }
++}
++
+ /*
+ * Read current time and date in RTC
+ */
+@@ -449,6 +469,8 @@ static int wm831x_rtc_probe(struct platf
+ alm_irq, ret);
+ }
+
++ wm831x_rtc_add_randomness(wm831x);
++
+ return 0;
+
+ err:
net-feed-dev-random-with-the-mac-address-when-registering-a-device.patch
random-use-the-arch-specific-rng-in-xfer_secondary_pool.patch
random-add-new-get_random_bytes_arch-function.patch
+random-add-tracepoints-for-easier-debugging-and-verification.patch
+maintainers-theodore-ts-o-is-taking-over-the-random-driver.patch
+rtc-wm831x-feed-the-write-counter-into-device_add_randomness.patch
+mfd-wm831x-feed-the-device-uuid-into-device_add_randomness.patch
+random-remove-rand_initialize_irq.patch
+random-add-comment-to-random_initialize.patch
+dmi-feed-dmi-table-to-dev-random-driver.patch
+random-mix-in-architectural-randomness-in-extract_buf.patch