diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv/rng.c')
-rw-r--r-- | arch/powerpc/platforms/powernv/rng.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 80db43944afe..6eb808ff637e 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c | |||
@@ -24,12 +24,22 @@ | |||
24 | 24 | ||
25 | struct powernv_rng { | 25 | struct powernv_rng { |
26 | void __iomem *regs; | 26 | void __iomem *regs; |
27 | void __iomem *regs_real; | ||
27 | unsigned long mask; | 28 | unsigned long mask; |
28 | }; | 29 | }; |
29 | 30 | ||
30 | static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); | 31 | static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng); |
31 | 32 | ||
32 | 33 | ||
34 | int powernv_hwrng_present(void) | ||
35 | { | ||
36 | struct powernv_rng *rng; | ||
37 | |||
38 | rng = get_cpu_var(powernv_rng); | ||
39 | put_cpu_var(rng); | ||
40 | return rng != NULL; | ||
41 | } | ||
42 | |||
33 | static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val) | 43 | static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val) |
34 | { | 44 | { |
35 | unsigned long parity; | 45 | unsigned long parity; |
@@ -46,6 +56,17 @@ static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val) | |||
46 | return val; | 56 | return val; |
47 | } | 57 | } |
48 | 58 | ||
59 | int powernv_get_random_real_mode(unsigned long *v) | ||
60 | { | ||
61 | struct powernv_rng *rng; | ||
62 | |||
63 | rng = raw_cpu_read(powernv_rng); | ||
64 | |||
65 | *v = rng_whiten(rng, in_rm64(rng->regs_real)); | ||
66 | |||
67 | return 1; | ||
68 | } | ||
69 | |||
49 | int powernv_get_random_long(unsigned long *v) | 70 | int powernv_get_random_long(unsigned long *v) |
50 | { | 71 | { |
51 | struct powernv_rng *rng; | 72 | struct powernv_rng *rng; |
@@ -80,12 +101,20 @@ static __init void rng_init_per_cpu(struct powernv_rng *rng, | |||
80 | static __init int rng_create(struct device_node *dn) | 101 | static __init int rng_create(struct device_node *dn) |
81 | { | 102 | { |
82 | struct powernv_rng *rng; | 103 | struct powernv_rng *rng; |
104 | struct resource res; | ||
83 | unsigned long val; | 105 | unsigned long val; |
84 | 106 | ||
85 | rng = kzalloc(sizeof(*rng), GFP_KERNEL); | 107 | rng = kzalloc(sizeof(*rng), GFP_KERNEL); |
86 | if (!rng) | 108 | if (!rng) |
87 | return -ENOMEM; | 109 | return -ENOMEM; |
88 | 110 | ||
111 | if (of_address_to_resource(dn, 0, &res)) { | ||
112 | kfree(rng); | ||
113 | return -ENXIO; | ||
114 | } | ||
115 | |||
116 | rng->regs_real = (void __iomem *)res.start; | ||
117 | |||
89 | rng->regs = of_iomap(dn, 0); | 118 | rng->regs = of_iomap(dn, 0); |
90 | if (!rng->regs) { | 119 | if (!rng->regs) { |
91 | kfree(rng); | 120 | kfree(rng); |