aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/hw_random
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/char/hw_random
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/char/hw_random')
-rw-r--r--drivers/char/hw_random/Kconfig88
-rw-r--r--drivers/char/hw_random/Makefile5
-rw-r--r--drivers/char/hw_random/atmel-rng.c155
-rw-r--r--drivers/char/hw_random/bcm63xx-rng.c175
-rw-r--r--drivers/char/hw_random/exynos-rng.c182
-rw-r--r--drivers/char/hw_random/ixp4xx-rng.c5
-rw-r--r--drivers/char/hw_random/mxc-rnga.c127
-rw-r--r--drivers/char/hw_random/n2-drv.c23
-rw-r--r--drivers/char/hw_random/nomadik-rng.c15
-rw-r--r--drivers/char/hw_random/octeon-rng.c32
-rw-r--r--drivers/char/hw_random/omap-rng.c146
-rw-r--r--drivers/char/hw_random/pasemi-rng.c16
-rw-r--r--drivers/char/hw_random/picoxcell-rng.c16
-rw-r--r--drivers/char/hw_random/ppc4xx-rng.c16
-rw-r--r--drivers/char/hw_random/pseries-rng.c96
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c19
-rw-r--r--drivers/char/hw_random/tpm-rng.c50
-rw-r--r--drivers/char/hw_random/tx4939-rng.c5
-rw-r--r--drivers/char/hw_random/virtio-rng.c42
19 files changed, 258 insertions, 955 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index c5a0262251b..1d2ebc7a494 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -60,33 +60,6 @@ config HW_RANDOM_AMD
60 60
61 If unsure, say Y. 61 If unsure, say Y.
62 62
63config HW_RANDOM_ATMEL
64 tristate "Atmel Random Number Generator support"
65 depends on HW_RANDOM && HAVE_CLK
66 default (HW_RANDOM && ARCH_AT91)
67 ---help---
68 This driver provides kernel-side support for the Random Number
69 Generator hardware found on Atmel AT91 devices.
70
71 To compile this driver as a module, choose M here: the
72 module will be called atmel-rng.
73
74 If unsure, say Y.
75
76config HW_RANDOM_BCM63XX
77 tristate "Broadcom BCM63xx Random Number Generator support"
78 depends on HW_RANDOM && BCM63XX
79 default HW_RANDOM
80 ---help---
81 This driver provides kernel-side support for the Random Number
82 Generator hardware found on the Broadcom BCM63xx SoCs.
83
84 To compile this driver as a module, choose M here: the
85 module will be called bcm63xx-rng
86
87 If unusure, say Y.
88
89
90config HW_RANDOM_GEODE 63config HW_RANDOM_GEODE
91 tristate "AMD Geode HW Random Number Generator support" 64 tristate "AMD Geode HW Random Number Generator support"
92 depends on HW_RANDOM && X86_32 && PCI 65 depends on HW_RANDOM && X86_32 && PCI
@@ -127,12 +100,12 @@ config HW_RANDOM_VIA
127 If unsure, say Y. 100 If unsure, say Y.
128 101
129config HW_RANDOM_IXP4XX 102config HW_RANDOM_IXP4XX
130 tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" 103 tristate "Intel IXP4xx NPU HW Random Number Generator support"
131 depends on HW_RANDOM && ARCH_IXP4XX 104 depends on HW_RANDOM && ARCH_IXP4XX
132 default HW_RANDOM 105 default HW_RANDOM
133 ---help--- 106 ---help---
134 This driver provides kernel-side support for the Pseudo-Random 107 This driver provides kernel-side support for the Random
135 Number Generator hardware found on the Intel IXP45x/46x NPU. 108 Number Generator hardware found on the Intel IXP4xx NPU.
136 109
137 To compile this driver as a module, choose M here: the 110 To compile this driver as a module, choose M here: the
138 module will be called ixp4xx-rng. 111 module will be called ixp4xx-rng.
@@ -216,7 +189,7 @@ config HW_RANDOM_MXC_RNGA
216 189
217config HW_RANDOM_NOMADIK 190config HW_RANDOM_NOMADIK
218 tristate "ST-Ericsson Nomadik Random Number Generator support" 191 tristate "ST-Ericsson Nomadik Random Number Generator support"
219 depends on HW_RANDOM && ARCH_NOMADIK 192 depends on HW_RANDOM && PLAT_NOMADIK
220 ---help--- 193 ---help---
221 This driver provides kernel-side support for the Random Number 194 This driver provides kernel-side support for the Random Number
222 Generator hardware found on ST-Ericsson SoCs (8815 and 8500). 195 Generator hardware found on ST-Ericsson SoCs (8815 and 8500).
@@ -249,56 +222,3 @@ config HW_RANDOM_PPC4XX
249 module will be called ppc4xx-rng. 222 module will be called ppc4xx-rng.
250 223
251 If unsure, say N. 224 If unsure, say N.
252
253config UML_RANDOM
254 depends on UML
255 tristate "Hardware random number generator"
256 help
257 This option enables UML's "hardware" random number generator. It
258 attaches itself to the host's /dev/random, supplying as much entropy
259 as the host has, rather than the small amount the UML gets from its
260 own drivers. It registers itself as a standard hardware random number
261 generator, major 10, minor 183, and the canonical device name is
262 /dev/hwrng.
263 The way to make use of this is to install the rng-tools package
264 (check your distro, or download from
265 http://sourceforge.net/projects/gkernel/). rngd periodically reads
266 /dev/hwrng and injects the entropy into /dev/random.
267
268config HW_RANDOM_PSERIES
269 tristate "pSeries HW Random Number Generator support"
270 depends on HW_RANDOM && PPC64 && IBMVIO
271 default HW_RANDOM
272 ---help---
273 This driver provides kernel-side support for the Random Number
274 Generator hardware found on POWER7+ machines and above
275
276 To compile this driver as a module, choose M here: the
277 module will be called pseries-rng.
278
279 If unsure, say Y.
280
281config HW_RANDOM_EXYNOS
282 tristate "EXYNOS HW random number generator support"
283 depends on HW_RANDOM && HAS_IOMEM && HAVE_CLK
284 ---help---
285 This driver provides kernel-side support for the Random Number
286 Generator hardware found on EXYNOS SOCs.
287
288 To compile this driver as a module, choose M here: the
289 module will be called exynos-rng.
290
291 If unsure, say Y.
292
293config HW_RANDOM_TPM
294 tristate "TPM HW Random Number Generator support"
295 depends on HW_RANDOM && TCG_TPM
296 default HW_RANDOM
297 ---help---
298 This driver provides kernel-side support for the Random Number
299 Generator in the Trusted Platform Module
300
301 To compile this driver as a module, choose M here: the
302 module will be called tpm-rng.
303
304 If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 1fd7eec9fbf..c88f244c8a7 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -7,8 +7,6 @@ rng-core-y := core.o
7obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o 7obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
8obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o 8obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
9obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o 9obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
10obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
11obj-$(CONFIG_HW_RANDOM_BCM63XX) += bcm63xx-rng.o
12obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o 10obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
13obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o 11obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
14n2-rng-y := n2-drv.o n2-asm.o 12n2-rng-y := n2-drv.o n2-asm.o
@@ -23,6 +21,3 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
23obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o 21obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
24obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o 22obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
25obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o 23obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
26obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
27obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
28obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
deleted file mode 100644
index 7c73d4aca36..00000000000
--- a/drivers/char/hw_random/atmel-rng.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/*
2 * Copyright (c) 2011 Peter Korsgaard <jacmet@sunsite.dk>
3 *
4 * This file is licensed under the terms of the GNU General Public
5 * License version 2. This program is licensed "as is" without any
6 * warranty of any kind, whether express or implied.
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/slab.h>
12#include <linux/err.h>
13#include <linux/clk.h>
14#include <linux/io.h>
15#include <linux/hw_random.h>
16#include <linux/platform_device.h>
17
18#define TRNG_CR 0x00
19#define TRNG_ISR 0x1c
20#define TRNG_ODATA 0x50
21
22#define TRNG_KEY 0x524e4700 /* RNG */
23
24struct atmel_trng {
25 struct clk *clk;
26 void __iomem *base;
27 struct hwrng rng;
28};
29
30static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max,
31 bool wait)
32{
33 struct atmel_trng *trng = container_of(rng, struct atmel_trng, rng);
34 u32 *data = buf;
35
36 /* data ready? */
37 if (readl(trng->base + TRNG_ISR) & 1) {
38 *data = readl(trng->base + TRNG_ODATA);
39 /*
40 ensure data ready is only set again AFTER the next data
41 word is ready in case it got set between checking ISR
42 and reading ODATA, so we don't risk re-reading the
43 same word
44 */
45 readl(trng->base + TRNG_ISR);
46 return 4;
47 } else
48 return 0;
49}
50
51static int atmel_trng_probe(struct platform_device *pdev)
52{
53 struct atmel_trng *trng;
54 struct resource *res;
55 int ret;
56
57 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
58 if (!res)
59 return -EINVAL;
60
61 trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
62 if (!trng)
63 return -ENOMEM;
64
65 if (!devm_request_mem_region(&pdev->dev, res->start,
66 resource_size(res), pdev->name))
67 return -EBUSY;
68
69 trng->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
70 if (!trng->base)
71 return -EBUSY;
72
73 trng->clk = clk_get(&pdev->dev, NULL);
74 if (IS_ERR(trng->clk))
75 return PTR_ERR(trng->clk);
76
77 ret = clk_enable(trng->clk);
78 if (ret)
79 goto err_enable;
80
81 writel(TRNG_KEY | 1, trng->base + TRNG_CR);
82 trng->rng.name = pdev->name;
83 trng->rng.read = atmel_trng_read;
84
85 ret = hwrng_register(&trng->rng);
86 if (ret)
87 goto err_register;
88
89 platform_set_drvdata(pdev, trng);
90
91 return 0;
92
93err_register:
94 clk_disable(trng->clk);
95err_enable:
96 clk_put(trng->clk);
97
98 return ret;
99}
100
101static int atmel_trng_remove(struct platform_device *pdev)
102{
103 struct atmel_trng *trng = platform_get_drvdata(pdev);
104
105 hwrng_unregister(&trng->rng);
106
107 writel(TRNG_KEY, trng->base + TRNG_CR);
108 clk_disable(trng->clk);
109 clk_put(trng->clk);
110
111 platform_set_drvdata(pdev, NULL);
112
113 return 0;
114}
115
116#ifdef CONFIG_PM
117static int atmel_trng_suspend(struct device *dev)
118{
119 struct atmel_trng *trng = dev_get_drvdata(dev);
120
121 clk_disable(trng->clk);
122
123 return 0;
124}
125
126static int atmel_trng_resume(struct device *dev)
127{
128 struct atmel_trng *trng = dev_get_drvdata(dev);
129
130 return clk_enable(trng->clk);
131}
132
133static const struct dev_pm_ops atmel_trng_pm_ops = {
134 .suspend = atmel_trng_suspend,
135 .resume = atmel_trng_resume,
136};
137#endif /* CONFIG_PM */
138
139static struct platform_driver atmel_trng_driver = {
140 .probe = atmel_trng_probe,
141 .remove = atmel_trng_remove,
142 .driver = {
143 .name = "atmel-trng",
144 .owner = THIS_MODULE,
145#ifdef CONFIG_PM
146 .pm = &atmel_trng_pm_ops,
147#endif /* CONFIG_PM */
148 },
149};
150
151module_platform_driver(atmel_trng_driver);
152
153MODULE_LICENSE("GPL");
154MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
155MODULE_DESCRIPTION("Atmel true random number generator driver");
diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c
deleted file mode 100644
index f343b7d0dfa..00000000000
--- a/drivers/char/hw_random/bcm63xx-rng.c
+++ /dev/null
@@ -1,175 +0,0 @@
1/*
2 * Broadcom BCM63xx Random Number Generator support
3 *
4 * Copyright (C) 2011, Florian Fainelli <florian@openwrt.org>
5 * Copyright (C) 2009, Broadcom Corporation
6 *
7 */
8#include <linux/module.h>
9#include <linux/slab.h>
10#include <linux/io.h>
11#include <linux/err.h>
12#include <linux/clk.h>
13#include <linux/platform_device.h>
14#include <linux/hw_random.h>
15
16#include <bcm63xx_io.h>
17#include <bcm63xx_regs.h>
18
19struct bcm63xx_rng_priv {
20 struct clk *clk;
21 void __iomem *regs;
22};
23
24#define to_rng_priv(rng) ((struct bcm63xx_rng_priv *)rng->priv)
25
26static int bcm63xx_rng_init(struct hwrng *rng)
27{
28 struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
29 u32 val;
30
31 val = bcm_readl(priv->regs + RNG_CTRL);
32 val |= RNG_EN;
33 bcm_writel(val, priv->regs + RNG_CTRL);
34
35 return 0;
36}
37
38static void bcm63xx_rng_cleanup(struct hwrng *rng)
39{
40 struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
41 u32 val;
42
43 val = bcm_readl(priv->regs + RNG_CTRL);
44 val &= ~RNG_EN;
45 bcm_writel(val, priv->regs + RNG_CTRL);
46}
47
48static int bcm63xx_rng_data_present(struct hwrng *rng, int wait)
49{
50 struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
51
52 return bcm_readl(priv->regs + RNG_STAT) & RNG_AVAIL_MASK;
53}
54
55static int bcm63xx_rng_data_read(struct hwrng *rng, u32 *data)
56{
57 struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
58
59 *data = bcm_readl(priv->regs + RNG_DATA);
60
61 return 4;
62}
63
64static int bcm63xx_rng_probe(struct platform_device *pdev)
65{
66 struct resource *r;
67 struct clk *clk;
68 int ret;
69 struct bcm63xx_rng_priv *priv;
70 struct hwrng *rng;
71
72 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
73 if (!r) {
74 dev_err(&pdev->dev, "no iomem resource\n");
75 ret = -ENXIO;
76 goto out;
77 }
78
79 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
80 if (!priv) {
81 dev_err(&pdev->dev, "no memory for private structure\n");
82 ret = -ENOMEM;
83 goto out;
84 }
85
86 rng = kzalloc(sizeof(*rng), GFP_KERNEL);
87 if (!rng) {
88 dev_err(&pdev->dev, "no memory for rng structure\n");
89 ret = -ENOMEM;
90 goto out_free_priv;
91 }
92
93 platform_set_drvdata(pdev, rng);
94 rng->priv = (unsigned long)priv;
95 rng->name = pdev->name;
96 rng->init = bcm63xx_rng_init;
97 rng->cleanup = bcm63xx_rng_cleanup;
98 rng->data_present = bcm63xx_rng_data_present;
99 rng->data_read = bcm63xx_rng_data_read;
100
101 clk = clk_get(&pdev->dev, "ipsec");
102 if (IS_ERR(clk)) {
103 dev_err(&pdev->dev, "no clock for device\n");
104 ret = PTR_ERR(clk);
105 goto out_free_rng;
106 }
107
108 priv->clk = clk;
109
110 if (!devm_request_mem_region(&pdev->dev, r->start,
111 resource_size(r), pdev->name)) {
112 dev_err(&pdev->dev, "request mem failed");
113 ret = -ENOMEM;
114 goto out_free_rng;
115 }
116
117 priv->regs = devm_ioremap_nocache(&pdev->dev, r->start,
118 resource_size(r));
119 if (!priv->regs) {
120 dev_err(&pdev->dev, "ioremap failed");
121 ret = -ENOMEM;
122 goto out_free_rng;
123 }
124
125 clk_enable(clk);
126
127 ret = hwrng_register(rng);
128 if (ret) {
129 dev_err(&pdev->dev, "failed to register rng device\n");
130 goto out_clk_disable;
131 }
132
133 dev_info(&pdev->dev, "registered RNG driver\n");
134
135 return 0;
136
137out_clk_disable:
138 clk_disable(clk);
139out_free_rng:
140 platform_set_drvdata(pdev, NULL);
141 kfree(rng);
142out_free_priv:
143 kfree(priv);
144out:
145 return ret;
146}
147
148static int bcm63xx_rng_remove(struct platform_device *pdev)
149{
150 struct hwrng *rng = platform_get_drvdata(pdev);
151 struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
152
153 hwrng_unregister(rng);
154 clk_disable(priv->clk);
155 kfree(priv);
156 kfree(rng);
157 platform_set_drvdata(pdev, NULL);
158
159 return 0;
160}
161
162static struct platform_driver bcm63xx_rng_driver = {
163 .probe = bcm63xx_rng_probe,
164 .remove = bcm63xx_rng_remove,
165 .driver = {
166 .name = "bcm63xx-rng",
167 .owner = THIS_MODULE,
168 },
169};
170
171module_platform_driver(bcm63xx_rng_driver);
172
173MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
174MODULE_DESCRIPTION("Broadcom BCM63xx RNG driver");
175MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c
deleted file mode 100644
index 48bbfeca4b5..00000000000
--- a/drivers/char/hw_random/exynos-rng.c
+++ /dev/null
@@ -1,182 +0,0 @@
1/*
2 * exynos-rng.c - Random Number Generator driver for the exynos
3 *
4 * Copyright (C) 2012 Samsung Electronics
5 * Jonghwa Lee <jonghwa3.lee@smasung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation;
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/hw_random.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/io.h>
27#include <linux/platform_device.h>
28#include <linux/clk.h>
29#include <linux/pm_runtime.h>
30#include <linux/err.h>
31
32#define EXYNOS_PRNG_STATUS_OFFSET 0x10
33#define EXYNOS_PRNG_SEED_OFFSET 0x140
34#define EXYNOS_PRNG_OUT1_OFFSET 0x160
35#define SEED_SETTING_DONE BIT(1)
36#define PRNG_START 0x18
37#define PRNG_DONE BIT(5)
38#define EXYNOS_AUTOSUSPEND_DELAY 100
39
40struct exynos_rng {
41 struct device *dev;
42 struct hwrng rng;
43 void __iomem *mem;
44 struct clk *clk;
45};
46
47static u32 exynos_rng_readl(struct exynos_rng *rng, u32 offset)
48{
49 return __raw_readl(rng->mem + offset);
50}
51
52static void exynos_rng_writel(struct exynos_rng *rng, u32 val, u32 offset)
53{
54 __raw_writel(val, rng->mem + offset);
55}
56
57static int exynos_init(struct hwrng *rng)
58{
59 struct exynos_rng *exynos_rng = container_of(rng,
60 struct exynos_rng, rng);
61 int i;
62 int ret = 0;
63
64 pm_runtime_get_sync(exynos_rng->dev);
65
66 for (i = 0 ; i < 5 ; i++)
67 exynos_rng_writel(exynos_rng, jiffies,
68 EXYNOS_PRNG_SEED_OFFSET + 4*i);
69
70 if (!(exynos_rng_readl(exynos_rng, EXYNOS_PRNG_STATUS_OFFSET)
71 & SEED_SETTING_DONE))
72 ret = -EIO;
73
74 pm_runtime_put_noidle(exynos_rng->dev);
75
76 return ret;
77}
78
79static int exynos_read(struct hwrng *rng, void *buf,
80 size_t max, bool wait)
81{
82 struct exynos_rng *exynos_rng = container_of(rng,
83 struct exynos_rng, rng);
84 u32 *data = buf;
85
86 pm_runtime_get_sync(exynos_rng->dev);
87
88 exynos_rng_writel(exynos_rng, PRNG_START, 0);
89
90 while (!(exynos_rng_readl(exynos_rng,
91 EXYNOS_PRNG_STATUS_OFFSET) & PRNG_DONE))
92 cpu_relax();
93
94 exynos_rng_writel(exynos_rng, PRNG_DONE, EXYNOS_PRNG_STATUS_OFFSET);
95
96 *data = exynos_rng_readl(exynos_rng, EXYNOS_PRNG_OUT1_OFFSET);
97
98 pm_runtime_mark_last_busy(exynos_rng->dev);
99 pm_runtime_autosuspend(exynos_rng->dev);
100
101 return 4;
102}
103
104static int exynos_rng_probe(struct platform_device *pdev)
105{
106 struct exynos_rng *exynos_rng;
107
108 exynos_rng = devm_kzalloc(&pdev->dev, sizeof(struct exynos_rng),
109 GFP_KERNEL);
110 if (!exynos_rng)
111 return -ENOMEM;
112
113 exynos_rng->dev = &pdev->dev;
114 exynos_rng->rng.name = "exynos";
115 exynos_rng->rng.init = exynos_init;
116 exynos_rng->rng.read = exynos_read;
117 exynos_rng->clk = devm_clk_get(&pdev->dev, "secss");
118 if (IS_ERR(exynos_rng->clk)) {
119 dev_err(&pdev->dev, "Couldn't get clock.\n");
120 return -ENOENT;
121 }
122
123 exynos_rng->mem = devm_request_and_ioremap(&pdev->dev,
124 platform_get_resource(pdev, IORESOURCE_MEM, 0));
125 if (!exynos_rng->mem)
126 return -EBUSY;
127
128 platform_set_drvdata(pdev, exynos_rng);
129
130 pm_runtime_set_autosuspend_delay(&pdev->dev, EXYNOS_AUTOSUSPEND_DELAY);
131 pm_runtime_use_autosuspend(&pdev->dev);
132 pm_runtime_enable(&pdev->dev);
133
134 return hwrng_register(&exynos_rng->rng);
135}
136
137static int exynos_rng_remove(struct platform_device *pdev)
138{
139 struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
140
141 hwrng_unregister(&exynos_rng->rng);
142
143 return 0;
144}
145
146static int exynos_rng_runtime_suspend(struct device *dev)
147{
148 struct platform_device *pdev = to_platform_device(dev);
149 struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
150
151 clk_disable_unprepare(exynos_rng->clk);
152
153 return 0;
154}
155
156static int exynos_rng_runtime_resume(struct device *dev)
157{
158 struct platform_device *pdev = to_platform_device(dev);
159 struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
160
161 return clk_prepare_enable(exynos_rng->clk);
162}
163
164
165UNIVERSAL_DEV_PM_OPS(exynos_rng_pm_ops, exynos_rng_runtime_suspend,
166 exynos_rng_runtime_resume, NULL);
167
168static struct platform_driver exynos_rng_driver = {
169 .driver = {
170 .name = "exynos-rng",
171 .owner = THIS_MODULE,
172 .pm = &exynos_rng_pm_ops,
173 },
174 .probe = exynos_rng_probe,
175 .remove = exynos_rng_remove,
176};
177
178module_platform_driver(exynos_rng_driver);
179
180MODULE_DESCRIPTION("EXYNOS 4 H/W Random Number Generator driver");
181MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
182MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c
index beec1627db3..263567f5f39 100644
--- a/drivers/char/hw_random/ixp4xx-rng.c
+++ b/drivers/char/hw_random/ixp4xx-rng.c
@@ -45,9 +45,6 @@ static int __init ixp4xx_rng_init(void)
45 void __iomem * rng_base; 45 void __iomem * rng_base;
46 int err; 46 int err;
47 47
48 if (!cpu_is_ixp46x()) /* includes IXP455 */
49 return -ENOSYS;
50
51 rng_base = ioremap(0x70002100, 4); 48 rng_base = ioremap(0x70002100, 4);
52 if (!rng_base) 49 if (!rng_base)
53 return -ENOMEM; 50 return -ENOMEM;
@@ -71,5 +68,5 @@ module_init(ixp4xx_rng_init);
71module_exit(ixp4xx_rng_exit); 68module_exit(ixp4xx_rng_exit);
72 69
73MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); 70MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
74MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); 71MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx");
75MODULE_LICENSE("GPL"); 72MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c
index f05d85713fd..187c6be80f4 100644
--- a/drivers/char/hw_random/mxc-rnga.c
+++ b/drivers/char/hw_random/mxc-rnga.c
@@ -24,7 +24,6 @@
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/hw_random.h> 26#include <linux/hw_random.h>
27#include <linux/delay.h>
28#include <linux/io.h> 27#include <linux/io.h>
29 28
30/* RNGA Registers */ 29/* RNGA Registers */
@@ -59,47 +58,38 @@
59#define RNGA_STATUS_LAST_READ_STATUS 0x00000002 58#define RNGA_STATUS_LAST_READ_STATUS 0x00000002
60#define RNGA_STATUS_SECURITY_VIOLATION 0x00000001 59#define RNGA_STATUS_SECURITY_VIOLATION 0x00000001
61 60
62struct mxc_rng { 61static struct platform_device *rng_dev;
63 struct device *dev;
64 struct hwrng rng;
65 void __iomem *mem;
66 struct clk *clk;
67};
68 62
69static int mxc_rnga_data_present(struct hwrng *rng, int wait) 63static int mxc_rnga_data_present(struct hwrng *rng)
70{ 64{
71 int i; 65 int level;
72 struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); 66 void __iomem *rng_base = (void __iomem *)rng->priv;
73 67
74 for (i = 0; i < 20; i++) { 68 /* how many random numbers is in FIFO? [0-16] */
75 /* how many random numbers are in FIFO? [0-16] */ 69 level = ((__raw_readl(rng_base + RNGA_STATUS) &
76 int level = (__raw_readl(mxc_rng->mem + RNGA_STATUS) & 70 RNGA_STATUS_LEVEL_MASK) >> 8);
77 RNGA_STATUS_LEVEL_MASK) >> 8; 71
78 if (level || !wait) 72 return level > 0 ? 1 : 0;
79 return !!level;
80 udelay(10);
81 }
82 return 0;
83} 73}
84 74
85static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) 75static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
86{ 76{
87 int err; 77 int err;
88 u32 ctrl; 78 u32 ctrl;
89 struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); 79 void __iomem *rng_base = (void __iomem *)rng->priv;
90 80
91 /* retrieve a random number from FIFO */ 81 /* retrieve a random number from FIFO */
92 *data = __raw_readl(mxc_rng->mem + RNGA_OUTPUT_FIFO); 82 *data = __raw_readl(rng_base + RNGA_OUTPUT_FIFO);
93 83
94 /* some error while reading this random number? */ 84 /* some error while reading this random number? */
95 err = __raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_ERROR_INT; 85 err = __raw_readl(rng_base + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;
96 86
97 /* if error: clear error interrupt, but doesn't return random number */ 87 /* if error: clear error interrupt, but doesn't return random number */
98 if (err) { 88 if (err) {
99 dev_dbg(mxc_rng->dev, "Error while reading random number!\n"); 89 dev_dbg(&rng_dev->dev, "Error while reading random number!\n");
100 ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); 90 ctrl = __raw_readl(rng_base + RNGA_CONTROL);
101 __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT, 91 __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT,
102 mxc_rng->mem + RNGA_CONTROL); 92 rng_base + RNGA_CONTROL);
103 return 0; 93 return 0;
104 } else 94 } else
105 return 4; 95 return 4;
@@ -108,22 +98,22 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
108static int mxc_rnga_init(struct hwrng *rng) 98static int mxc_rnga_init(struct hwrng *rng)
109{ 99{
110 u32 ctrl, osc; 100 u32 ctrl, osc;
111 struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); 101 void __iomem *rng_base = (void __iomem *)rng->priv;
112 102
113 /* wake up */ 103 /* wake up */
114 ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); 104 ctrl = __raw_readl(rng_base + RNGA_CONTROL);
115 __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, mxc_rng->mem + RNGA_CONTROL); 105 __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, rng_base + RNGA_CONTROL);
116 106
117 /* verify if oscillator is working */ 107 /* verify if oscillator is working */
118 osc = __raw_readl(mxc_rng->mem + RNGA_STATUS); 108 osc = __raw_readl(rng_base + RNGA_STATUS);
119 if (osc & RNGA_STATUS_OSC_DEAD) { 109 if (osc & RNGA_STATUS_OSC_DEAD) {
120 dev_err(mxc_rng->dev, "RNGA Oscillator is dead!\n"); 110 dev_err(&rng_dev->dev, "RNGA Oscillator is dead!\n");
121 return -ENODEV; 111 return -ENODEV;
122 } 112 }
123 113
124 /* go running */ 114 /* go running */
125 ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); 115 ctrl = __raw_readl(rng_base + RNGA_CONTROL);
126 __raw_writel(ctrl | RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL); 116 __raw_writel(ctrl | RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
127 117
128 return 0; 118 return 0;
129} 119}
@@ -131,40 +121,40 @@ static int mxc_rnga_init(struct hwrng *rng)
131static void mxc_rnga_cleanup(struct hwrng *rng) 121static void mxc_rnga_cleanup(struct hwrng *rng)
132{ 122{
133 u32 ctrl; 123 u32 ctrl;
134 struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); 124 void __iomem *rng_base = (void __iomem *)rng->priv;
135 125
136 ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); 126 ctrl = __raw_readl(rng_base + RNGA_CONTROL);
137 127
138 /* stop rnga */ 128 /* stop rnga */
139 __raw_writel(ctrl & ~RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL); 129 __raw_writel(ctrl & ~RNGA_CONTROL_GO, rng_base + RNGA_CONTROL);
140} 130}
141 131
132static struct hwrng mxc_rnga = {
133 .name = "mxc-rnga",
134 .init = mxc_rnga_init,
135 .cleanup = mxc_rnga_cleanup,
136 .data_present = mxc_rnga_data_present,
137 .data_read = mxc_rnga_data_read
138};
139
142static int __init mxc_rnga_probe(struct platform_device *pdev) 140static int __init mxc_rnga_probe(struct platform_device *pdev)
143{ 141{
144 int err = -ENODEV; 142 int err = -ENODEV;
143 struct clk *clk;
145 struct resource *res, *mem; 144 struct resource *res, *mem;
146 struct mxc_rng *mxc_rng; 145 void __iomem *rng_base = NULL;
147 146
148 mxc_rng = devm_kzalloc(&pdev->dev, sizeof(struct mxc_rng), 147 if (rng_dev)
149 GFP_KERNEL); 148 return -EBUSY;
150 if (!mxc_rng) 149
151 return -ENOMEM; 150 clk = clk_get(&pdev->dev, "rng");
152 151 if (IS_ERR(clk)) {
153 mxc_rng->dev = &pdev->dev;
154 mxc_rng->rng.name = "mxc-rnga";
155 mxc_rng->rng.init = mxc_rnga_init;
156 mxc_rng->rng.cleanup = mxc_rnga_cleanup,
157 mxc_rng->rng.data_present = mxc_rnga_data_present,
158 mxc_rng->rng.data_read = mxc_rnga_data_read,
159
160 mxc_rng->clk = devm_clk_get(&pdev->dev, NULL);
161 if (IS_ERR(mxc_rng->clk)) {
162 dev_err(&pdev->dev, "Could not get rng_clk!\n"); 152 dev_err(&pdev->dev, "Could not get rng_clk!\n");
163 err = PTR_ERR(mxc_rng->clk); 153 err = PTR_ERR(clk);
164 goto out; 154 goto out;
165 } 155 }
166 156
167 clk_prepare_enable(mxc_rng->clk); 157 clk_enable(clk);
168 158
169 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 159 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
170 if (!res) { 160 if (!res) {
@@ -178,27 +168,36 @@ static int __init mxc_rnga_probe(struct platform_device *pdev)
178 goto err_region; 168 goto err_region;
179 } 169 }
180 170
181 mxc_rng->mem = ioremap(res->start, resource_size(res)); 171 rng_base = ioremap(res->start, resource_size(res));
182 if (!mxc_rng->mem) { 172 if (!rng_base) {
183 err = -ENOMEM; 173 err = -ENOMEM;
184 goto err_ioremap; 174 goto err_ioremap;
185 } 175 }
186 176
187 err = hwrng_register(&mxc_rng->rng); 177 mxc_rnga.priv = (unsigned long)rng_base;
178
179 err = hwrng_register(&mxc_rnga);
188 if (err) { 180 if (err) {
189 dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err); 181 dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err);
190 goto err_ioremap; 182 goto err_register;
191 } 183 }
192 184
185 rng_dev = pdev;
186
193 dev_info(&pdev->dev, "MXC RNGA Registered.\n"); 187 dev_info(&pdev->dev, "MXC RNGA Registered.\n");
194 188
195 return 0; 189 return 0;
196 190
191err_register:
192 iounmap(rng_base);
193 rng_base = NULL;
194
197err_ioremap: 195err_ioremap:
198 release_mem_region(res->start, resource_size(res)); 196 release_mem_region(res->start, resource_size(res));
199 197
200err_region: 198err_region:
201 clk_disable_unprepare(mxc_rng->clk); 199 clk_disable(clk);
200 clk_put(clk);
202 201
203out: 202out:
204 return err; 203 return err;
@@ -207,15 +206,17 @@ out:
207static int __exit mxc_rnga_remove(struct platform_device *pdev) 206static int __exit mxc_rnga_remove(struct platform_device *pdev)
208{ 207{
209 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 208 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
210 struct mxc_rng *mxc_rng = platform_get_drvdata(pdev); 209 void __iomem *rng_base = (void __iomem *)mxc_rnga.priv;
210 struct clk *clk = clk_get(&pdev->dev, "rng");
211 211
212 hwrng_unregister(&mxc_rng->rng); 212 hwrng_unregister(&mxc_rnga);
213 213
214 iounmap(mxc_rng->mem); 214 iounmap(rng_base);
215 215
216 release_mem_region(res->start, resource_size(res)); 216 release_mem_region(res->start, resource_size(res));
217 217
218 clk_disable_unprepare(mxc_rng->clk); 218 clk_disable(clk);
219 clk_put(clk);
219 220
220 return 0; 221 return 0;
221} 222}
diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c
index 20b962e1d83..c3de70de00d 100644
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -25,7 +25,7 @@
25#define DRV_MODULE_VERSION "0.2" 25#define DRV_MODULE_VERSION "0.2"
26#define DRV_MODULE_RELDATE "July 27, 2011" 26#define DRV_MODULE_RELDATE "July 27, 2011"
27 27
28static char version[] = 28static char version[] __devinitdata =
29 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 29 DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
30 30
31MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); 31MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
@@ -611,7 +611,7 @@ static void n2rng_work(struct work_struct *work)
611 schedule_delayed_work(&np->work, HZ * 2); 611 schedule_delayed_work(&np->work, HZ * 2);
612} 612}
613 613
614static void n2rng_driver_version(void) 614static void __devinit n2rng_driver_version(void)
615{ 615{
616 static int n2rng_version_printed; 616 static int n2rng_version_printed;
617 617
@@ -620,7 +620,7 @@ static void n2rng_driver_version(void)
620} 620}
621 621
622static const struct of_device_id n2rng_match[]; 622static const struct of_device_id n2rng_match[];
623static int n2rng_probe(struct platform_device *op) 623static int __devinit n2rng_probe(struct platform_device *op)
624{ 624{
625 const struct of_device_id *match; 625 const struct of_device_id *match;
626 int multi_capable; 626 int multi_capable;
@@ -719,7 +719,7 @@ out:
719 return err; 719 return err;
720} 720}
721 721
722static int n2rng_remove(struct platform_device *op) 722static int __devexit n2rng_remove(struct platform_device *op)
723{ 723{
724 struct n2rng *np = dev_get_drvdata(&op->dev); 724 struct n2rng *np = dev_get_drvdata(&op->dev);
725 725
@@ -767,7 +767,18 @@ static struct platform_driver n2rng_driver = {
767 .of_match_table = n2rng_match, 767 .of_match_table = n2rng_match,
768 }, 768 },
769 .probe = n2rng_probe, 769 .probe = n2rng_probe,
770 .remove = n2rng_remove, 770 .remove = __devexit_p(n2rng_remove),
771}; 771};
772 772
773module_platform_driver(n2rng_driver); 773static int __init n2rng_init(void)
774{
775 return platform_driver_register(&n2rng_driver);
776}
777
778static void __exit n2rng_exit(void)
779{
780 platform_driver_unregister(&n2rng_driver);
781}
782
783module_init(n2rng_init);
784module_exit(n2rng_exit);
diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c
index 96de0249e59..52e08ca3ccd 100644
--- a/drivers/char/hw_random/nomadik-rng.c
+++ b/drivers/char/hw_random/nomadik-rng.c
@@ -95,8 +95,6 @@ static struct amba_id nmk_rng_ids[] = {
95 {0, 0}, 95 {0, 0},
96}; 96};
97 97
98MODULE_DEVICE_TABLE(amba, nmk_rng_ids);
99
100static struct amba_driver nmk_rng_driver = { 98static struct amba_driver nmk_rng_driver = {
101 .drv = { 99 .drv = {
102 .owner = THIS_MODULE, 100 .owner = THIS_MODULE,
@@ -107,6 +105,17 @@ static struct amba_driver nmk_rng_driver = {
107 .id_table = nmk_rng_ids, 105 .id_table = nmk_rng_ids,
108}; 106};
109 107
110module_amba_driver(nmk_rng_driver); 108static int __init nmk_rng_init(void)
109{
110 return amba_driver_register(&nmk_rng_driver);
111}
112
113static void __devexit nmk_rng_exit(void)
114{
115 amba_driver_unregister(&nmk_rng_driver);
116}
117
118module_init(nmk_rng_init);
119module_exit(nmk_rng_exit);
111 120
112MODULE_LICENSE("GPL"); 121MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
index 1eada566ca7..9cd0feca318 100644
--- a/drivers/char/hw_random/octeon-rng.c
+++ b/drivers/char/hw_random/octeon-rng.c
@@ -56,7 +56,7 @@ static int octeon_rng_data_read(struct hwrng *rng, u32 *data)
56 return sizeof(u32); 56 return sizeof(u32);
57} 57}
58 58
59static int octeon_rng_probe(struct platform_device *pdev) 59static int __devinit octeon_rng_probe(struct platform_device *pdev)
60{ 60{
61 struct resource *res_ports; 61 struct resource *res_ports;
62 struct resource *res_result; 62 struct resource *res_result;
@@ -75,35 +75,42 @@ static int octeon_rng_probe(struct platform_device *pdev)
75 75
76 res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0); 76 res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0);
77 if (!res_ports) 77 if (!res_ports)
78 return -ENOENT; 78 goto err_ports;
79 79
80 res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1); 80 res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1);
81 if (!res_result) 81 if (!res_result)
82 return -ENOENT; 82 goto err_ports;
83 83
84 84
85 rng->control_status = devm_ioremap_nocache(&pdev->dev, 85 rng->control_status = devm_ioremap_nocache(&pdev->dev,
86 res_ports->start, 86 res_ports->start,
87 sizeof(u64)); 87 sizeof(u64));
88 if (!rng->control_status) 88 if (!rng->control_status)
89 return -ENOENT; 89 goto err_ports;
90 90
91 rng->result = devm_ioremap_nocache(&pdev->dev, 91 rng->result = devm_ioremap_nocache(&pdev->dev,
92 res_result->start, 92 res_result->start,
93 sizeof(u64)); 93 sizeof(u64));
94 if (!rng->result) 94 if (!rng->result)
95 return -ENOENT; 95 goto err_r;
96 96
97 rng->ops = ops; 97 rng->ops = ops;
98 98
99 dev_set_drvdata(&pdev->dev, &rng->ops); 99 dev_set_drvdata(&pdev->dev, &rng->ops);
100 ret = hwrng_register(&rng->ops); 100 ret = hwrng_register(&rng->ops);
101 if (ret) 101 if (ret)
102 return -ENOENT; 102 goto err;
103 103
104 dev_info(&pdev->dev, "Octeon Random Number Generator\n"); 104 dev_info(&pdev->dev, "Octeon Random Number Generator\n");
105 105
106 return 0; 106 return 0;
107err:
108 devm_iounmap(&pdev->dev, rng->control_status);
109err_r:
110 devm_iounmap(&pdev->dev, rng->result);
111err_ports:
112 devm_kfree(&pdev->dev, rng);
113 return -ENOENT;
107} 114}
108 115
109static int __exit octeon_rng_remove(struct platform_device *pdev) 116static int __exit octeon_rng_remove(struct platform_device *pdev)
@@ -124,7 +131,18 @@ static struct platform_driver octeon_rng_driver = {
124 .remove = __exit_p(octeon_rng_remove), 131 .remove = __exit_p(octeon_rng_remove),
125}; 132};
126 133
127module_platform_driver(octeon_rng_driver); 134static int __init octeon_rng_mod_init(void)
135{
136 return platform_driver_register(&octeon_rng_driver);
137}
138
139static void __exit octeon_rng_mod_exit(void)
140{
141 platform_driver_unregister(&octeon_rng_driver);
142}
143
144module_init(octeon_rng_mod_init);
145module_exit(octeon_rng_mod_exit);
128 146
129MODULE_AUTHOR("David Daney"); 147MODULE_AUTHOR("David Daney");
130MODULE_LICENSE("GPL"); 148MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index d8c54e25376..b757fac3cd1 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -18,12 +18,11 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/random.h> 20#include <linux/random.h>
21#include <linux/clk.h>
21#include <linux/err.h> 22#include <linux/err.h>
22#include <linux/platform_device.h> 23#include <linux/platform_device.h>
23#include <linux/hw_random.h> 24#include <linux/hw_random.h>
24#include <linux/delay.h> 25#include <linux/delay.h>
25#include <linux/slab.h>
26#include <linux/pm_runtime.h>
27 26
28#include <asm/io.h> 27#include <asm/io.h>
29 28
@@ -45,36 +44,26 @@
45#define RNG_SYSSTATUS 0x44 /* System status 44#define RNG_SYSSTATUS 0x44 /* System status
46 [0] = RESETDONE */ 45 [0] = RESETDONE */
47 46
48/** 47static void __iomem *rng_base;
49 * struct omap_rng_private_data - RNG IP block-specific data 48static struct clk *rng_ick;
50 * @base: virtual address of the beginning of the RNG IP block registers 49static struct platform_device *rng_dev;
51 * @mem_res: struct resource * for the IP block registers physical memory
52 */
53struct omap_rng_private_data {
54 void __iomem *base;
55 struct resource *mem_res;
56};
57 50
58static inline u32 omap_rng_read_reg(struct omap_rng_private_data *priv, int reg) 51static inline u32 omap_rng_read_reg(int reg)
59{ 52{
60 return __raw_readl(priv->base + reg); 53 return __raw_readl(rng_base + reg);
61} 54}
62 55
63static inline void omap_rng_write_reg(struct omap_rng_private_data *priv, 56static inline void omap_rng_write_reg(int reg, u32 val)
64 int reg, u32 val)
65{ 57{
66 __raw_writel(val, priv->base + reg); 58 __raw_writel(val, rng_base + reg);
67} 59}
68 60
69static int omap_rng_data_present(struct hwrng *rng, int wait) 61static int omap_rng_data_present(struct hwrng *rng, int wait)
70{ 62{
71 struct omap_rng_private_data *priv;
72 int data, i; 63 int data, i;
73 64
74 priv = (struct omap_rng_private_data *)rng->priv;
75
76 for (i = 0; i < 20; i++) { 65 for (i = 0; i < 20; i++) {
77 data = omap_rng_read_reg(priv, RNG_STAT_REG) ? 0 : 1; 66 data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
78 if (data || !wait) 67 if (data || !wait)
79 break; 68 break;
80 /* RNG produces data fast enough (2+ MBit/sec, even 69 /* RNG produces data fast enough (2+ MBit/sec, even
@@ -89,13 +78,9 @@ static int omap_rng_data_present(struct hwrng *rng, int wait)
89 78
90static int omap_rng_data_read(struct hwrng *rng, u32 *data) 79static int omap_rng_data_read(struct hwrng *rng, u32 *data)
91{ 80{
92 struct omap_rng_private_data *priv; 81 *data = omap_rng_read_reg(RNG_OUT_REG);
93
94 priv = (struct omap_rng_private_data *)rng->priv;
95
96 *data = omap_rng_read_reg(priv, RNG_OUT_REG);
97 82
98 return sizeof(u32); 83 return 4;
99} 84}
100 85
101static struct hwrng omap_rng_ops = { 86static struct hwrng omap_rng_ops = {
@@ -104,102 +89,111 @@ static struct hwrng omap_rng_ops = {
104 .data_read = omap_rng_data_read, 89 .data_read = omap_rng_data_read,
105}; 90};
106 91
107static int omap_rng_probe(struct platform_device *pdev) 92static int __devinit omap_rng_probe(struct platform_device *pdev)
108{ 93{
109 struct omap_rng_private_data *priv; 94 struct resource *res;
110 int ret; 95 int ret;
111 96
112 priv = kzalloc(sizeof(struct omap_rng_private_data), GFP_KERNEL); 97 /*
113 if (!priv) { 98 * A bit ugly, and it will never actually happen but there can
114 dev_err(&pdev->dev, "could not allocate memory\n"); 99 * be only one RNG and this catches any bork
115 return -ENOMEM; 100 */
116 }; 101 if (rng_dev)
102 return -EBUSY;
103
104 if (cpu_is_omap24xx()) {
105 rng_ick = clk_get(&pdev->dev, "ick");
106 if (IS_ERR(rng_ick)) {
107 dev_err(&pdev->dev, "Could not get rng_ick\n");
108 ret = PTR_ERR(rng_ick);
109 return ret;
110 } else
111 clk_enable(rng_ick);
112 }
117 113
118 omap_rng_ops.priv = (unsigned long)priv; 114 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
119 dev_set_drvdata(&pdev->dev, priv);
120 115
121 priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 116 if (!res) {
122 if (!priv->mem_res) {
123 ret = -ENOENT; 117 ret = -ENOENT;
124 goto err_ioremap; 118 goto err_region;
125 } 119 }
126 120
127 priv->base = devm_request_and_ioremap(&pdev->dev, priv->mem_res); 121 if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
128 if (!priv->base) { 122 ret = -EBUSY;
123 goto err_region;
124 }
125
126 dev_set_drvdata(&pdev->dev, res);
127 rng_base = ioremap(res->start, resource_size(res));
128 if (!rng_base) {
129 ret = -ENOMEM; 129 ret = -ENOMEM;
130 goto err_ioremap; 130 goto err_ioremap;
131 } 131 }
132 dev_set_drvdata(&pdev->dev, priv);
133
134 pm_runtime_enable(&pdev->dev);
135 pm_runtime_get_sync(&pdev->dev);
136 132
137 ret = hwrng_register(&omap_rng_ops); 133 ret = hwrng_register(&omap_rng_ops);
138 if (ret) 134 if (ret)
139 goto err_register; 135 goto err_register;
140 136
141 dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", 137 dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
142 omap_rng_read_reg(priv, RNG_REV_REG)); 138 omap_rng_read_reg(RNG_REV_REG));
139 omap_rng_write_reg(RNG_MASK_REG, 0x1);
143 140
144 omap_rng_write_reg(priv, RNG_MASK_REG, 0x1); 141 rng_dev = pdev;
145 142
146 return 0; 143 return 0;
147 144
148err_register: 145err_register:
149 priv->base = NULL; 146 iounmap(rng_base);
150 pm_runtime_disable(&pdev->dev); 147 rng_base = NULL;
151err_ioremap: 148err_ioremap:
152 kfree(priv); 149 release_mem_region(res->start, resource_size(res));
153 150err_region:
151 if (cpu_is_omap24xx()) {
152 clk_disable(rng_ick);
153 clk_put(rng_ick);
154 }
154 return ret; 155 return ret;
155} 156}
156 157
157static int __exit omap_rng_remove(struct platform_device *pdev) 158static int __exit omap_rng_remove(struct platform_device *pdev)
158{ 159{
159 struct omap_rng_private_data *priv = dev_get_drvdata(&pdev->dev); 160 struct resource *res = dev_get_drvdata(&pdev->dev);
160 161
161 hwrng_unregister(&omap_rng_ops); 162 hwrng_unregister(&omap_rng_ops);
162 163
163 omap_rng_write_reg(priv, RNG_MASK_REG, 0x0); 164 omap_rng_write_reg(RNG_MASK_REG, 0x0);
164 165
165 pm_runtime_put_sync(&pdev->dev); 166 iounmap(rng_base);
166 pm_runtime_disable(&pdev->dev);
167 167
168 release_mem_region(priv->mem_res->start, resource_size(priv->mem_res)); 168 if (cpu_is_omap24xx()) {
169 clk_disable(rng_ick);
170 clk_put(rng_ick);
171 }
169 172
170 kfree(priv); 173 release_mem_region(res->start, resource_size(res));
174 rng_base = NULL;
171 175
172 return 0; 176 return 0;
173} 177}
174 178
175#ifdef CONFIG_PM_SLEEP 179#ifdef CONFIG_PM
176 180
177static int omap_rng_suspend(struct device *dev) 181static int omap_rng_suspend(struct platform_device *pdev, pm_message_t message)
178{ 182{
179 struct omap_rng_private_data *priv = dev_get_drvdata(dev); 183 omap_rng_write_reg(RNG_MASK_REG, 0x0);
180
181 omap_rng_write_reg(priv, RNG_MASK_REG, 0x0);
182 pm_runtime_put_sync(dev);
183
184 return 0; 184 return 0;
185} 185}
186 186
187static int omap_rng_resume(struct device *dev) 187static int omap_rng_resume(struct platform_device *pdev)
188{ 188{
189 struct omap_rng_private_data *priv = dev_get_drvdata(dev); 189 omap_rng_write_reg(RNG_MASK_REG, 0x1);
190
191 pm_runtime_get_sync(dev);
192 omap_rng_write_reg(priv, RNG_MASK_REG, 0x1);
193
194 return 0; 190 return 0;
195} 191}
196 192
197static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume);
198#define OMAP_RNG_PM (&omap_rng_pm)
199
200#else 193#else
201 194
202#define OMAP_RNG_PM NULL 195#define omap_rng_suspend NULL
196#define omap_rng_resume NULL
203 197
204#endif 198#endif
205 199
@@ -210,14 +204,18 @@ static struct platform_driver omap_rng_driver = {
210 .driver = { 204 .driver = {
211 .name = "omap_rng", 205 .name = "omap_rng",
212 .owner = THIS_MODULE, 206 .owner = THIS_MODULE,
213 .pm = OMAP_RNG_PM,
214 }, 207 },
215 .probe = omap_rng_probe, 208 .probe = omap_rng_probe,
216 .remove = __exit_p(omap_rng_remove), 209 .remove = __exit_p(omap_rng_remove),
210 .suspend = omap_rng_suspend,
211 .resume = omap_rng_resume
217}; 212};
218 213
219static int __init omap_rng_init(void) 214static int __init omap_rng_init(void)
220{ 215{
216 if (!cpu_is_omap16xx() && !cpu_is_omap24xx())
217 return -ENODEV;
218
221 return platform_driver_register(&omap_rng_driver); 219 return platform_driver_register(&omap_rng_driver);
222} 220}
223 221
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c
index c6df5b29af0..1d504815e6d 100644
--- a/drivers/char/hw_random/pasemi-rng.c
+++ b/drivers/char/hw_random/pasemi-rng.c
@@ -94,7 +94,7 @@ static struct hwrng pasemi_rng = {
94 .data_read = pasemi_rng_data_read, 94 .data_read = pasemi_rng_data_read,
95}; 95};
96 96
97static int rng_probe(struct platform_device *ofdev) 97static int __devinit rng_probe(struct platform_device *ofdev)
98{ 98{
99 void __iomem *rng_regs; 99 void __iomem *rng_regs;
100 struct device_node *rng_np = ofdev->dev.of_node; 100 struct device_node *rng_np = ofdev->dev.of_node;
@@ -122,7 +122,7 @@ static int rng_probe(struct platform_device *ofdev)
122 return err; 122 return err;
123} 123}
124 124
125static int rng_remove(struct platform_device *dev) 125static int __devexit rng_remove(struct platform_device *dev)
126{ 126{
127 void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv; 127 void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv;
128 128
@@ -148,7 +148,17 @@ static struct platform_driver rng_driver = {
148 .remove = rng_remove, 148 .remove = rng_remove,
149}; 149};
150 150
151module_platform_driver(rng_driver); 151static int __init rng_init(void)
152{
153 return platform_driver_register(&rng_driver);
154}
155module_init(rng_init);
156
157static void __exit rng_exit(void)
158{
159 platform_driver_unregister(&rng_driver);
160}
161module_exit(rng_exit);
152 162
153MODULE_LICENSE("GPL"); 163MODULE_LICENSE("GPL");
154MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>"); 164MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>");
diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c
index 973b95113ed..990d55a5e3e 100644
--- a/drivers/char/hw_random/picoxcell-rng.c
+++ b/drivers/char/hw_random/picoxcell-rng.c
@@ -151,7 +151,7 @@ err_enable:
151 return ret; 151 return ret;
152} 152}
153 153
154static int picoxcell_trng_remove(struct platform_device *pdev) 154static int __devexit picoxcell_trng_remove(struct platform_device *pdev)
155{ 155{
156 hwrng_unregister(&picoxcell_trng); 156 hwrng_unregister(&picoxcell_trng);
157 clk_disable(rng_clk); 157 clk_disable(rng_clk);
@@ -181,7 +181,7 @@ static const struct dev_pm_ops picoxcell_trng_pm_ops = {
181 181
182static struct platform_driver picoxcell_trng_driver = { 182static struct platform_driver picoxcell_trng_driver = {
183 .probe = picoxcell_trng_probe, 183 .probe = picoxcell_trng_probe,
184 .remove = picoxcell_trng_remove, 184 .remove = __devexit_p(picoxcell_trng_remove),
185 .driver = { 185 .driver = {
186 .name = "picoxcell-trng", 186 .name = "picoxcell-trng",
187 .owner = THIS_MODULE, 187 .owner = THIS_MODULE,
@@ -191,7 +191,17 @@ static struct platform_driver picoxcell_trng_driver = {
191 }, 191 },
192}; 192};
193 193
194module_platform_driver(picoxcell_trng_driver); 194static int __init picoxcell_trng_init(void)
195{
196 return platform_driver_register(&picoxcell_trng_driver);
197}
198module_init(picoxcell_trng_init);
199
200static void __exit picoxcell_trng_exit(void)
201{
202 platform_driver_unregister(&picoxcell_trng_driver);
203}
204module_exit(picoxcell_trng_exit);
195 205
196MODULE_LICENSE("GPL"); 206MODULE_LICENSE("GPL");
197MODULE_AUTHOR("Jamie Iles"); 207MODULE_AUTHOR("Jamie Iles");
diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c
index 732c330805f..b8afa6a4ff6 100644
--- a/drivers/char/hw_random/ppc4xx-rng.c
+++ b/drivers/char/hw_random/ppc4xx-rng.c
@@ -90,7 +90,7 @@ static struct hwrng ppc4xx_rng = {
90 .data_read = ppc4xx_rng_data_read, 90 .data_read = ppc4xx_rng_data_read,
91}; 91};
92 92
93static int ppc4xx_rng_probe(struct platform_device *dev) 93static int __devinit ppc4xx_rng_probe(struct platform_device *dev)
94{ 94{
95 void __iomem *rng_regs; 95 void __iomem *rng_regs;
96 int err = 0; 96 int err = 0;
@@ -111,7 +111,7 @@ static int ppc4xx_rng_probe(struct platform_device *dev)
111 return err; 111 return err;
112} 112}
113 113
114static int ppc4xx_rng_remove(struct platform_device *dev) 114static int __devexit ppc4xx_rng_remove(struct platform_device *dev)
115{ 115{
116 void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv; 116 void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
117 117
@@ -139,7 +139,17 @@ static struct platform_driver ppc4xx_rng_driver = {
139 .remove = ppc4xx_rng_remove, 139 .remove = ppc4xx_rng_remove,
140}; 140};
141 141
142module_platform_driver(ppc4xx_rng_driver); 142static int __init ppc4xx_rng_init(void)
143{
144 return platform_driver_register(&ppc4xx_rng_driver);
145}
146module_init(ppc4xx_rng_init);
147
148static void __exit ppc4xx_rng_exit(void)
149{
150 platform_driver_unregister(&ppc4xx_rng_driver);
151}
152module_exit(ppc4xx_rng_exit);
143 153
144MODULE_LICENSE("GPL"); 154MODULE_LICENSE("GPL");
145MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>"); 155MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>");
diff --git a/drivers/char/hw_random/pseries-rng.c b/drivers/char/hw_random/pseries-rng.c
deleted file mode 100644
index 5f1197929f0..00000000000
--- a/drivers/char/hw_random/pseries-rng.c
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * Copyright (C) 2010 Michael Neuling IBM Corporation
3 *
4 * Driver for the pseries hardware RNG for POWER7+ and above
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/hw_random.h>
22#include <asm/vio.h>
23
24#define MODULE_NAME "pseries-rng"
25
26static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
27{
28 if (plpar_hcall(H_RANDOM, (unsigned long *)data) != H_SUCCESS) {
29 printk(KERN_ERR "pseries rng hcall error\n");
30 return 0;
31 }
32 return 8;
33}
34
35/**
36 * pseries_rng_get_desired_dma - Return desired DMA allocate for CMO operations
37 *
38 * This is a required function for a driver to operate in a CMO environment
39 * but this device does not make use of DMA allocations, return 0.
40 *
41 * Return value:
42 * Number of bytes of IO data the driver will need to perform well -> 0
43 */
44static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev)
45{
46 return 0;
47};
48
49static struct hwrng pseries_rng = {
50 .name = MODULE_NAME,
51 .data_read = pseries_rng_data_read,
52};
53
54static int __init pseries_rng_probe(struct vio_dev *dev,
55 const struct vio_device_id *id)
56{
57 return hwrng_register(&pseries_rng);
58}
59
60static int __exit pseries_rng_remove(struct vio_dev *dev)
61{
62 hwrng_unregister(&pseries_rng);
63 return 0;
64}
65
66static struct vio_device_id pseries_rng_driver_ids[] = {
67 { "ibm,random-v1", "ibm,random"},
68 { "", "" }
69};
70MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids);
71
72static struct vio_driver pseries_rng_driver = {
73 .name = MODULE_NAME,
74 .probe = pseries_rng_probe,
75 .remove = pseries_rng_remove,
76 .get_desired_dma = pseries_rng_get_desired_dma,
77 .id_table = pseries_rng_driver_ids
78};
79
80static int __init rng_init(void)
81{
82 printk(KERN_INFO "Registering IBM pSeries RNG driver\n");
83 return vio_register_driver(&pseries_rng_driver);
84}
85
86module_init(rng_init);
87
88static void __exit rng_exit(void)
89{
90 vio_unregister_driver(&pseries_rng_driver);
91}
92module_exit(rng_exit);
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR("Michael Neuling <mikey@neuling.org>");
96MODULE_DESCRIPTION("H/W RNG driver for IBM pSeries processors");
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index 849db199c02..a8428e6f64a 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -88,7 +88,7 @@ static struct hwrng timeriomem_rng_ops = {
88 .priv = 0, 88 .priv = 0,
89}; 89};
90 90
91static int timeriomem_rng_probe(struct platform_device *pdev) 91static int __devinit timeriomem_rng_probe(struct platform_device *pdev)
92{ 92{
93 struct resource *res; 93 struct resource *res;
94 int ret; 94 int ret;
@@ -130,7 +130,7 @@ failed:
130 return ret; 130 return ret;
131} 131}
132 132
133static int timeriomem_rng_remove(struct platform_device *pdev) 133static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
134{ 134{
135 del_timer_sync(&timeriomem_rng_timer); 135 del_timer_sync(&timeriomem_rng_timer);
136 hwrng_unregister(&timeriomem_rng_ops); 136 hwrng_unregister(&timeriomem_rng_ops);
@@ -146,10 +146,21 @@ static struct platform_driver timeriomem_rng_driver = {
146 .owner = THIS_MODULE, 146 .owner = THIS_MODULE,
147 }, 147 },
148 .probe = timeriomem_rng_probe, 148 .probe = timeriomem_rng_probe,
149 .remove = timeriomem_rng_remove, 149 .remove = __devexit_p(timeriomem_rng_remove),
150}; 150};
151 151
152module_platform_driver(timeriomem_rng_driver); 152static int __init timeriomem_rng_init(void)
153{
154 return platform_driver_register(&timeriomem_rng_driver);
155}
156
157static void __exit timeriomem_rng_exit(void)
158{
159 platform_driver_unregister(&timeriomem_rng_driver);
160}
161
162module_init(timeriomem_rng_init);
163module_exit(timeriomem_rng_exit);
153 164
154MODULE_LICENSE("GPL"); 165MODULE_LICENSE("GPL");
155MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); 166MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
diff --git a/drivers/char/hw_random/tpm-rng.c b/drivers/char/hw_random/tpm-rng.c
deleted file mode 100644
index d6d448266f0..00000000000
--- a/drivers/char/hw_random/tpm-rng.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * Copyright (C) 2012 Kent Yoder IBM Corporation
3 *
4 * HWRNG interfaces to pull RNG data from a TPM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/hw_random.h>
22#include <linux/tpm.h>
23
24#define MODULE_NAME "tpm-rng"
25
26static int tpm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
27{
28 return tpm_get_random(TPM_ANY_NUM, data, max);
29}
30
31static struct hwrng tpm_rng = {
32 .name = MODULE_NAME,
33 .read = tpm_rng_read,
34};
35
36static int __init rng_init(void)
37{
38 return hwrng_register(&tpm_rng);
39}
40module_init(rng_init);
41
42static void __exit rng_exit(void)
43{
44 hwrng_unregister(&tpm_rng);
45}
46module_exit(rng_exit);
47
48MODULE_LICENSE("GPL v2");
49MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>");
50MODULE_DESCRIPTION("RNG driver for TPM devices");
diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c
index de473ef3882..0bc0cb70210 100644
--- a/drivers/char/hw_random/tx4939-rng.c
+++ b/drivers/char/hw_random/tx4939-rng.c
@@ -115,7 +115,10 @@ static int __init tx4939_rng_probe(struct platform_device *dev)
115 rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); 115 rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
116 if (!rngdev) 116 if (!rngdev)
117 return -ENOMEM; 117 return -ENOMEM;
118 rngdev->base = devm_request_and_ioremap(&dev->dev, r); 118 if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r),
119 dev_name(&dev->dev)))
120 return -EBUSY;
121 rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
119 if (!rngdev->base) 122 if (!rngdev->base)
120 return -EBUSY; 123 return -EBUSY;
121 124
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index b65c1039595..75f1cbd61c1 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -23,7 +23,6 @@
23#include <linux/spinlock.h> 23#include <linux/spinlock.h>
24#include <linux/virtio.h> 24#include <linux/virtio.h>
25#include <linux/virtio_rng.h> 25#include <linux/virtio_rng.h>
26#include <linux/module.h>
27 26
28static struct virtqueue *vq; 27static struct virtqueue *vq;
29static unsigned int data_avail; 28static unsigned int data_avail;
@@ -47,7 +46,7 @@ static void register_buffer(u8 *buf, size_t size)
47 sg_init_one(&sg, buf, size); 46 sg_init_one(&sg, buf, size);
48 47
49 /* There should always be room for one buffer. */ 48 /* There should always be room for one buffer. */
50 if (virtqueue_add_buf(vq, &sg, 0, 1, buf, GFP_KERNEL) < 0) 49 if (virtqueue_add_buf(vq, &sg, 0, 1, buf) < 0)
51 BUG(); 50 BUG();
52 51
53 virtqueue_kick(vq); 52 virtqueue_kick(vq);
@@ -55,7 +54,6 @@ static void register_buffer(u8 *buf, size_t size)
55 54
56static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) 55static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
57{ 56{
58 int ret;
59 57
60 if (!busy) { 58 if (!busy) {
61 busy = true; 59 busy = true;
@@ -66,9 +64,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
66 if (!wait) 64 if (!wait)
67 return 0; 65 return 0;
68 66
69 ret = wait_for_completion_killable(&have_data); 67 wait_for_completion(&have_data);
70 if (ret < 0)
71 return ret;
72 68
73 busy = false; 69 busy = false;
74 70
@@ -88,7 +84,7 @@ static struct hwrng virtio_hwrng = {
88 .read = virtio_read, 84 .read = virtio_read,
89}; 85};
90 86
91static int probe_common(struct virtio_device *vdev) 87static int virtrng_probe(struct virtio_device *vdev)
92{ 88{
93 int err; 89 int err;
94 90
@@ -106,37 +102,13 @@ static int probe_common(struct virtio_device *vdev)
106 return 0; 102 return 0;
107} 103}
108 104
109static void remove_common(struct virtio_device *vdev) 105static void __devexit virtrng_remove(struct virtio_device *vdev)
110{ 106{
111 vdev->config->reset(vdev); 107 vdev->config->reset(vdev);
112 busy = false;
113 hwrng_unregister(&virtio_hwrng); 108 hwrng_unregister(&virtio_hwrng);
114 vdev->config->del_vqs(vdev); 109 vdev->config->del_vqs(vdev);
115} 110}
116 111
117static int virtrng_probe(struct virtio_device *vdev)
118{
119 return probe_common(vdev);
120}
121
122static void virtrng_remove(struct virtio_device *vdev)
123{
124 remove_common(vdev);
125}
126
127#ifdef CONFIG_PM
128static int virtrng_freeze(struct virtio_device *vdev)
129{
130 remove_common(vdev);
131 return 0;
132}
133
134static int virtrng_restore(struct virtio_device *vdev)
135{
136 return probe_common(vdev);
137}
138#endif
139
140static struct virtio_device_id id_table[] = { 112static struct virtio_device_id id_table[] = {
141 { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID }, 113 { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID },
142 { 0 }, 114 { 0 },
@@ -147,11 +119,7 @@ static struct virtio_driver virtio_rng_driver = {
147 .driver.owner = THIS_MODULE, 119 .driver.owner = THIS_MODULE,
148 .id_table = id_table, 120 .id_table = id_table,
149 .probe = virtrng_probe, 121 .probe = virtrng_probe,
150 .remove = virtrng_remove, 122 .remove = __devexit_p(virtrng_remove),
151#ifdef CONFIG_PM
152 .freeze = virtrng_freeze,
153 .restore = virtrng_restore,
154#endif
155}; 123};
156 124
157static int __init init(void) 125static int __init init(void)