diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/char/hw_random | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/char/hw_random')
-rw-r--r-- | drivers/char/hw_random/Kconfig | 88 | ||||
-rw-r--r-- | drivers/char/hw_random/Makefile | 5 | ||||
-rw-r--r-- | drivers/char/hw_random/atmel-rng.c | 155 | ||||
-rw-r--r-- | drivers/char/hw_random/bcm63xx-rng.c | 175 | ||||
-rw-r--r-- | drivers/char/hw_random/exynos-rng.c | 182 | ||||
-rw-r--r-- | drivers/char/hw_random/ixp4xx-rng.c | 5 | ||||
-rw-r--r-- | drivers/char/hw_random/mxc-rnga.c | 127 | ||||
-rw-r--r-- | drivers/char/hw_random/n2-drv.c | 23 | ||||
-rw-r--r-- | drivers/char/hw_random/nomadik-rng.c | 15 | ||||
-rw-r--r-- | drivers/char/hw_random/octeon-rng.c | 32 | ||||
-rw-r--r-- | drivers/char/hw_random/omap-rng.c | 146 | ||||
-rw-r--r-- | drivers/char/hw_random/pasemi-rng.c | 16 | ||||
-rw-r--r-- | drivers/char/hw_random/picoxcell-rng.c | 16 | ||||
-rw-r--r-- | drivers/char/hw_random/ppc4xx-rng.c | 16 | ||||
-rw-r--r-- | drivers/char/hw_random/pseries-rng.c | 96 | ||||
-rw-r--r-- | drivers/char/hw_random/timeriomem-rng.c | 19 | ||||
-rw-r--r-- | drivers/char/hw_random/tpm-rng.c | 50 | ||||
-rw-r--r-- | drivers/char/hw_random/tx4939-rng.c | 5 | ||||
-rw-r--r-- | drivers/char/hw_random/virtio-rng.c | 42 |
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 | ||
63 | config 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 | |||
76 | config 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 | |||
90 | config HW_RANDOM_GEODE | 63 | config 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 | ||
129 | config HW_RANDOM_IXP4XX | 102 | config 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 | ||
217 | config HW_RANDOM_NOMADIK | 190 | config 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 | |||
253 | config 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 | |||
268 | config 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 | |||
281 | config 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 | |||
293 | config 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 | |||
7 | obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o | 7 | obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o |
8 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o | 8 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o |
9 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o | 9 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o |
10 | obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o | ||
11 | obj-$(CONFIG_HW_RANDOM_BCM63XX) += bcm63xx-rng.o | ||
12 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o | 10 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o |
13 | obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o | 11 | obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o |
14 | n2-rng-y := n2-drv.o n2-asm.o | 12 | n2-rng-y := n2-drv.o n2-asm.o |
@@ -23,6 +21,3 @@ obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o | |||
23 | obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o | 21 | obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o |
24 | obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o | 22 | obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o |
25 | obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o | 23 | obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o |
26 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o | ||
27 | obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o | ||
28 | obj-$(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 | |||
24 | struct atmel_trng { | ||
25 | struct clk *clk; | ||
26 | void __iomem *base; | ||
27 | struct hwrng rng; | ||
28 | }; | ||
29 | |||
30 | static 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 | |||
51 | static 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 | |||
93 | err_register: | ||
94 | clk_disable(trng->clk); | ||
95 | err_enable: | ||
96 | clk_put(trng->clk); | ||
97 | |||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | static 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 | ||
117 | static 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 | |||
126 | static 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 | |||
133 | static 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 | |||
139 | static 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 | |||
151 | module_platform_driver(atmel_trng_driver); | ||
152 | |||
153 | MODULE_LICENSE("GPL"); | ||
154 | MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); | ||
155 | MODULE_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 | |||
19 | struct 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 | |||
26 | static 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 | |||
38 | static 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 | |||
48 | static 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 | |||
55 | static 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 | |||
64 | static 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 | |||
137 | out_clk_disable: | ||
138 | clk_disable(clk); | ||
139 | out_free_rng: | ||
140 | platform_set_drvdata(pdev, NULL); | ||
141 | kfree(rng); | ||
142 | out_free_priv: | ||
143 | kfree(priv); | ||
144 | out: | ||
145 | return ret; | ||
146 | } | ||
147 | |||
148 | static 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 | |||
162 | static 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 | |||
171 | module_platform_driver(bcm63xx_rng_driver); | ||
172 | |||
173 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); | ||
174 | MODULE_DESCRIPTION("Broadcom BCM63xx RNG driver"); | ||
175 | MODULE_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 | |||
40 | struct exynos_rng { | ||
41 | struct device *dev; | ||
42 | struct hwrng rng; | ||
43 | void __iomem *mem; | ||
44 | struct clk *clk; | ||
45 | }; | ||
46 | |||
47 | static u32 exynos_rng_readl(struct exynos_rng *rng, u32 offset) | ||
48 | { | ||
49 | return __raw_readl(rng->mem + offset); | ||
50 | } | ||
51 | |||
52 | static void exynos_rng_writel(struct exynos_rng *rng, u32 val, u32 offset) | ||
53 | { | ||
54 | __raw_writel(val, rng->mem + offset); | ||
55 | } | ||
56 | |||
57 | static 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 | |||
79 | static 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 | |||
104 | static 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 | |||
137 | static 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 | |||
146 | static 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 | |||
156 | static 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 | |||
165 | UNIVERSAL_DEV_PM_OPS(exynos_rng_pm_ops, exynos_rng_runtime_suspend, | ||
166 | exynos_rng_runtime_resume, NULL); | ||
167 | |||
168 | static 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 | |||
178 | module_platform_driver(exynos_rng_driver); | ||
179 | |||
180 | MODULE_DESCRIPTION("EXYNOS 4 H/W Random Number Generator driver"); | ||
181 | MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); | ||
182 | MODULE_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); | |||
71 | module_exit(ixp4xx_rng_exit); | 68 | module_exit(ixp4xx_rng_exit); |
72 | 69 | ||
73 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); | 70 | MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); |
74 | MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); | 71 | MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); |
75 | MODULE_LICENSE("GPL"); | 72 | MODULE_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 | ||
62 | struct mxc_rng { | 61 | static struct platform_device *rng_dev; |
63 | struct device *dev; | ||
64 | struct hwrng rng; | ||
65 | void __iomem *mem; | ||
66 | struct clk *clk; | ||
67 | }; | ||
68 | 62 | ||
69 | static int mxc_rnga_data_present(struct hwrng *rng, int wait) | 63 | static 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 | ||
85 | static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) | 75 | static 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) | |||
108 | static int mxc_rnga_init(struct hwrng *rng) | 98 | static 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) | |||
131 | static void mxc_rnga_cleanup(struct hwrng *rng) | 121 | static 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 | ||
132 | static 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 | |||
142 | static int __init mxc_rnga_probe(struct platform_device *pdev) | 140 | static 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 | ||
191 | err_register: | ||
192 | iounmap(rng_base); | ||
193 | rng_base = NULL; | ||
194 | |||
197 | err_ioremap: | 195 | err_ioremap: |
198 | release_mem_region(res->start, resource_size(res)); | 196 | release_mem_region(res->start, resource_size(res)); |
199 | 197 | ||
200 | err_region: | 198 | err_region: |
201 | clk_disable_unprepare(mxc_rng->clk); | 199 | clk_disable(clk); |
200 | clk_put(clk); | ||
202 | 201 | ||
203 | out: | 202 | out: |
204 | return err; | 203 | return err; |
@@ -207,15 +206,17 @@ out: | |||
207 | static int __exit mxc_rnga_remove(struct platform_device *pdev) | 206 | static 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 | ||
28 | static char version[] = | 28 | static 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 | ||
31 | MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); | 31 | MODULE_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 | ||
614 | static void n2rng_driver_version(void) | 614 | static 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 | ||
622 | static const struct of_device_id n2rng_match[]; | 622 | static const struct of_device_id n2rng_match[]; |
623 | static int n2rng_probe(struct platform_device *op) | 623 | static 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 | ||
722 | static int n2rng_remove(struct platform_device *op) | 722 | static 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 | ||
773 | module_platform_driver(n2rng_driver); | 773 | static int __init n2rng_init(void) |
774 | { | ||
775 | return platform_driver_register(&n2rng_driver); | ||
776 | } | ||
777 | |||
778 | static void __exit n2rng_exit(void) | ||
779 | { | ||
780 | platform_driver_unregister(&n2rng_driver); | ||
781 | } | ||
782 | |||
783 | module_init(n2rng_init); | ||
784 | module_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 | ||
98 | MODULE_DEVICE_TABLE(amba, nmk_rng_ids); | ||
99 | |||
100 | static struct amba_driver nmk_rng_driver = { | 98 | static 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 | ||
110 | module_amba_driver(nmk_rng_driver); | 108 | static int __init nmk_rng_init(void) |
109 | { | ||
110 | return amba_driver_register(&nmk_rng_driver); | ||
111 | } | ||
112 | |||
113 | static void __devexit nmk_rng_exit(void) | ||
114 | { | ||
115 | amba_driver_unregister(&nmk_rng_driver); | ||
116 | } | ||
117 | |||
118 | module_init(nmk_rng_init); | ||
119 | module_exit(nmk_rng_exit); | ||
111 | 120 | ||
112 | MODULE_LICENSE("GPL"); | 121 | MODULE_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 | ||
59 | static int octeon_rng_probe(struct platform_device *pdev) | 59 | static 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; |
107 | err: | ||
108 | devm_iounmap(&pdev->dev, rng->control_status); | ||
109 | err_r: | ||
110 | devm_iounmap(&pdev->dev, rng->result); | ||
111 | err_ports: | ||
112 | devm_kfree(&pdev->dev, rng); | ||
113 | return -ENOENT; | ||
107 | } | 114 | } |
108 | 115 | ||
109 | static int __exit octeon_rng_remove(struct platform_device *pdev) | 116 | static 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 | ||
127 | module_platform_driver(octeon_rng_driver); | 134 | static int __init octeon_rng_mod_init(void) |
135 | { | ||
136 | return platform_driver_register(&octeon_rng_driver); | ||
137 | } | ||
138 | |||
139 | static void __exit octeon_rng_mod_exit(void) | ||
140 | { | ||
141 | platform_driver_unregister(&octeon_rng_driver); | ||
142 | } | ||
143 | |||
144 | module_init(octeon_rng_mod_init); | ||
145 | module_exit(octeon_rng_mod_exit); | ||
128 | 146 | ||
129 | MODULE_AUTHOR("David Daney"); | 147 | MODULE_AUTHOR("David Daney"); |
130 | MODULE_LICENSE("GPL"); | 148 | MODULE_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 | /** | 47 | static void __iomem *rng_base; |
49 | * struct omap_rng_private_data - RNG IP block-specific data | 48 | static struct clk *rng_ick; |
50 | * @base: virtual address of the beginning of the RNG IP block registers | 49 | static struct platform_device *rng_dev; |
51 | * @mem_res: struct resource * for the IP block registers physical memory | ||
52 | */ | ||
53 | struct omap_rng_private_data { | ||
54 | void __iomem *base; | ||
55 | struct resource *mem_res; | ||
56 | }; | ||
57 | 50 | ||
58 | static inline u32 omap_rng_read_reg(struct omap_rng_private_data *priv, int reg) | 51 | static 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 | ||
63 | static inline void omap_rng_write_reg(struct omap_rng_private_data *priv, | 56 | static 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 | ||
69 | static int omap_rng_data_present(struct hwrng *rng, int wait) | 61 | static 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 | ||
90 | static int omap_rng_data_read(struct hwrng *rng, u32 *data) | 79 | static 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 | ||
101 | static struct hwrng omap_rng_ops = { | 86 | static 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 | ||
107 | static int omap_rng_probe(struct platform_device *pdev) | 92 | static 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 | ||
148 | err_register: | 145 | err_register: |
149 | priv->base = NULL; | 146 | iounmap(rng_base); |
150 | pm_runtime_disable(&pdev->dev); | 147 | rng_base = NULL; |
151 | err_ioremap: | 148 | err_ioremap: |
152 | kfree(priv); | 149 | release_mem_region(res->start, resource_size(res)); |
153 | 150 | err_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 | ||
157 | static int __exit omap_rng_remove(struct platform_device *pdev) | 158 | static 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 | ||
177 | static int omap_rng_suspend(struct device *dev) | 181 | static 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 | ||
187 | static int omap_rng_resume(struct device *dev) | 187 | static 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 | ||
197 | static 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 | ||
219 | static int __init omap_rng_init(void) | 214 | static 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 | ||
97 | static int rng_probe(struct platform_device *ofdev) | 97 | static 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 | ||
125 | static int rng_remove(struct platform_device *dev) | 125 | static 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 | ||
151 | module_platform_driver(rng_driver); | 151 | static int __init rng_init(void) |
152 | { | ||
153 | return platform_driver_register(&rng_driver); | ||
154 | } | ||
155 | module_init(rng_init); | ||
156 | |||
157 | static void __exit rng_exit(void) | ||
158 | { | ||
159 | platform_driver_unregister(&rng_driver); | ||
160 | } | ||
161 | module_exit(rng_exit); | ||
152 | 162 | ||
153 | MODULE_LICENSE("GPL"); | 163 | MODULE_LICENSE("GPL"); |
154 | MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>"); | 164 | MODULE_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 | ||
154 | static int picoxcell_trng_remove(struct platform_device *pdev) | 154 | static 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 | ||
182 | static struct platform_driver picoxcell_trng_driver = { | 182 | static 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 | ||
194 | module_platform_driver(picoxcell_trng_driver); | 194 | static int __init picoxcell_trng_init(void) |
195 | { | ||
196 | return platform_driver_register(&picoxcell_trng_driver); | ||
197 | } | ||
198 | module_init(picoxcell_trng_init); | ||
199 | |||
200 | static void __exit picoxcell_trng_exit(void) | ||
201 | { | ||
202 | platform_driver_unregister(&picoxcell_trng_driver); | ||
203 | } | ||
204 | module_exit(picoxcell_trng_exit); | ||
195 | 205 | ||
196 | MODULE_LICENSE("GPL"); | 206 | MODULE_LICENSE("GPL"); |
197 | MODULE_AUTHOR("Jamie Iles"); | 207 | MODULE_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 | ||
93 | static int ppc4xx_rng_probe(struct platform_device *dev) | 93 | static 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 | ||
114 | static int ppc4xx_rng_remove(struct platform_device *dev) | 114 | static 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 | ||
142 | module_platform_driver(ppc4xx_rng_driver); | 142 | static int __init ppc4xx_rng_init(void) |
143 | { | ||
144 | return platform_driver_register(&ppc4xx_rng_driver); | ||
145 | } | ||
146 | module_init(ppc4xx_rng_init); | ||
147 | |||
148 | static void __exit ppc4xx_rng_exit(void) | ||
149 | { | ||
150 | platform_driver_unregister(&ppc4xx_rng_driver); | ||
151 | } | ||
152 | module_exit(ppc4xx_rng_exit); | ||
143 | 153 | ||
144 | MODULE_LICENSE("GPL"); | 154 | MODULE_LICENSE("GPL"); |
145 | MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>"); | 155 | MODULE_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 | |||
26 | static 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 | */ | ||
44 | static unsigned long pseries_rng_get_desired_dma(struct vio_dev *vdev) | ||
45 | { | ||
46 | return 0; | ||
47 | }; | ||
48 | |||
49 | static struct hwrng pseries_rng = { | ||
50 | .name = MODULE_NAME, | ||
51 | .data_read = pseries_rng_data_read, | ||
52 | }; | ||
53 | |||
54 | static 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 | |||
60 | static int __exit pseries_rng_remove(struct vio_dev *dev) | ||
61 | { | ||
62 | hwrng_unregister(&pseries_rng); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static struct vio_device_id pseries_rng_driver_ids[] = { | ||
67 | { "ibm,random-v1", "ibm,random"}, | ||
68 | { "", "" } | ||
69 | }; | ||
70 | MODULE_DEVICE_TABLE(vio, pseries_rng_driver_ids); | ||
71 | |||
72 | static 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 | |||
80 | static 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 | |||
86 | module_init(rng_init); | ||
87 | |||
88 | static void __exit rng_exit(void) | ||
89 | { | ||
90 | vio_unregister_driver(&pseries_rng_driver); | ||
91 | } | ||
92 | module_exit(rng_exit); | ||
93 | |||
94 | MODULE_LICENSE("GPL"); | ||
95 | MODULE_AUTHOR("Michael Neuling <mikey@neuling.org>"); | ||
96 | MODULE_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 | ||
91 | static int timeriomem_rng_probe(struct platform_device *pdev) | 91 | static 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 | ||
133 | static int timeriomem_rng_remove(struct platform_device *pdev) | 133 | static 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 | ||
152 | module_platform_driver(timeriomem_rng_driver); | 152 | static int __init timeriomem_rng_init(void) |
153 | { | ||
154 | return platform_driver_register(&timeriomem_rng_driver); | ||
155 | } | ||
156 | |||
157 | static void __exit timeriomem_rng_exit(void) | ||
158 | { | ||
159 | platform_driver_unregister(&timeriomem_rng_driver); | ||
160 | } | ||
161 | |||
162 | module_init(timeriomem_rng_init); | ||
163 | module_exit(timeriomem_rng_exit); | ||
153 | 164 | ||
154 | MODULE_LICENSE("GPL"); | 165 | MODULE_LICENSE("GPL"); |
155 | MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); | 166 | MODULE_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 | |||
26 | static 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 | |||
31 | static struct hwrng tpm_rng = { | ||
32 | .name = MODULE_NAME, | ||
33 | .read = tpm_rng_read, | ||
34 | }; | ||
35 | |||
36 | static int __init rng_init(void) | ||
37 | { | ||
38 | return hwrng_register(&tpm_rng); | ||
39 | } | ||
40 | module_init(rng_init); | ||
41 | |||
42 | static void __exit rng_exit(void) | ||
43 | { | ||
44 | hwrng_unregister(&tpm_rng); | ||
45 | } | ||
46 | module_exit(rng_exit); | ||
47 | |||
48 | MODULE_LICENSE("GPL v2"); | ||
49 | MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>"); | ||
50 | MODULE_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 | ||
28 | static struct virtqueue *vq; | 27 | static struct virtqueue *vq; |
29 | static unsigned int data_avail; | 28 | static 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 | ||
56 | static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) | 55 | static 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 | ||
91 | static int probe_common(struct virtio_device *vdev) | 87 | static 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 | ||
109 | static void remove_common(struct virtio_device *vdev) | 105 | static 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 | ||
117 | static int virtrng_probe(struct virtio_device *vdev) | ||
118 | { | ||
119 | return probe_common(vdev); | ||
120 | } | ||
121 | |||
122 | static void virtrng_remove(struct virtio_device *vdev) | ||
123 | { | ||
124 | remove_common(vdev); | ||
125 | } | ||
126 | |||
127 | #ifdef CONFIG_PM | ||
128 | static int virtrng_freeze(struct virtio_device *vdev) | ||
129 | { | ||
130 | remove_common(vdev); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int virtrng_restore(struct virtio_device *vdev) | ||
135 | { | ||
136 | return probe_common(vdev); | ||
137 | } | ||
138 | #endif | ||
139 | |||
140 | static struct virtio_device_id id_table[] = { | 112 | static 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 | ||
157 | static int __init init(void) | 125 | static int __init init(void) |