#define PPC_INST_CLRBHRB               0x7c00035c
 #define PPC_INST_COPY                  0x7c20060c
 #define PPC_INST_CP_ABORT              0x7c00068c
+#define PPC_INST_DARN                  0x7c0005e6
 #define PPC_INST_DCBA                  0x7c0005ec
 #define PPC_INST_DCBA_MASK             0xfc0007fe
 #define PPC_INST_DCBAL                 0x7c2005ec
 #define        PPC_CP_ABORT            stringify_in_c(.long PPC_INST_CP_ABORT)
 #define        PPC_COPY(a, b)          stringify_in_c(.long PPC_INST_COPY | \
                                        ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_DARN(t, l)         stringify_in_c(.long PPC_INST_DARN |  \
+                                               ___PPC_RT(t)       |  \
+                                               (((l) & 0x3) << 16))
 #define        PPC_DCBAL(a, b)         stringify_in_c(.long PPC_INST_DCBAL | \
                                        __PPC_RA(a) | __PPC_RB(b))
 #define        PPC_DCBZL(a, b)         stringify_in_c(.long PPC_INST_DCBZL | \
 
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <asm/archrandom.h>
+#include <asm/cputable.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/smp.h>
 
+#define DARN_ERR 0xFFFFFFFFFFFFFFFFul
 
 struct powernv_rng {
        void __iomem *regs;
        return 1;
 }
 
+int powernv_get_random_darn(unsigned long *v)
+{
+       unsigned long val;
+
+       /* Using DARN with L=1 - 64-bit conditioned random number */
+       asm volatile(PPC_DARN(%0, 1) : "=r"(val));
+
+       if (val == DARN_ERR)
+               return 0;
+
+       *v = val;
+
+       return 1;
+}
+
+static int initialise_darn(void)
+{
+       unsigned long val;
+       int i;
+
+       if (!cpu_has_feature(CPU_FTR_ARCH_300))
+               return -ENODEV;
+
+       for (i = 0; i < 10; i++) {
+               if (powernv_get_random_darn(&val)) {
+                       ppc_md.get_random_seed = powernv_get_random_darn;
+                       return 0;
+               }
+       }
+
+       pr_warn("Unable to use DARN for get_random_seed()\n");
+
+       return -EIO;
+}
+
 int powernv_get_random_long(unsigned long *v)
 {
        struct powernv_rng *rng;
                of_platform_device_create(dn, NULL, NULL);
        }
 
+       initialise_darn();
+
        return 0;
 }
 machine_subsys_initcall(powernv, rng_init);