aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-01 23:16:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-01 23:16:43 -0400
commit25498e5b3df931a3d52a6e0642ae242e4ee19488 (patch)
tree5a627d71015fde644d8c61a04f7718c2f0a748db /drivers/char
parent952414505f55afe5cd6dc004765076aa22b3ed7e (diff)
parent995a0605a6665858d73f9e80053414909be33f27 (diff)
Merge branch 'next/driver' of git://git.linaro.org/people/arnd/arm-soc
* 'next/driver' of git://git.linaro.org/people/arnd/arm-soc: hw_random: add driver for atmel true hardware random number generator ARM: at91: at91sam9g45: add trng clock and platform device MX53 Enable the AHCI SATA on MX53 SMD board MX53 Enable the AHCI SATA on MX53 LOCO board MX53 Enable the AHCI SATA on MX53 ARD board AHCI Add the AHCI SATA feature on the MX53 platforms Fix pata imx resource ARM: imx: Define functions for registering PATA ARM: imx: Add PATA clock support ARM: imx: Add PATA resources for other i.MX processors imx: efika: Enable pata. imx51: add pata clock imx51: add pata device Fix up trivial conflict (new selects next to each other from separate branches for EFIKA_COMMON) in arch/arm/mach-mx5/Kconfig
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/hw_random/Kconfig13
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/atmel-rng.c158
3 files changed, 172 insertions, 0 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 1d2ebc7a4947..e0135873ba9d 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -60,6 +60,19 @@ 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 && ARCH_AT91SAM9G45
66 default HW_RANDOM
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
63config HW_RANDOM_GEODE 76config HW_RANDOM_GEODE
64 tristate "AMD Geode HW Random Number Generator support" 77 tristate "AMD Geode HW Random Number Generator support"
65 depends on HW_RANDOM && X86_32 && PCI 78 depends on HW_RANDOM && X86_32 && PCI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index c88f244c8a71..b2ff5265a996 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -7,6 +7,7 @@ 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
10obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o 11obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
11obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o 12obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
12n2-rng-y := n2-drv.o n2-asm.o 13n2-rng-y := n2-drv.o n2-asm.o
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c
new file mode 100644
index 000000000000..241df2e76aba
--- /dev/null
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -0,0 +1,158 @@
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_ODATA) & 1) {
38 *data = readl(trng->base + TRNG_ODATA);
39 return 4;
40 } else
41 return 0;
42}
43
44static int atmel_trng_probe(struct platform_device *pdev)
45{
46 struct atmel_trng *trng;
47 struct resource *res;
48 int ret;
49
50 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
51 if (!res)
52 return -EINVAL;
53
54 trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
55 if (!trng)
56 return -ENOMEM;
57
58 if (!devm_request_mem_region(&pdev->dev, res->start,
59 resource_size(res), pdev->name))
60 return -EBUSY;
61
62 trng->base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
63 if (!trng->base)
64 return -EBUSY;
65
66 trng->clk = clk_get(&pdev->dev, NULL);
67 if (IS_ERR(trng->clk))
68 return PTR_ERR(trng->clk);
69
70 ret = clk_enable(trng->clk);
71 if (ret)
72 goto err_enable;
73
74 writel(TRNG_KEY | 1, trng->base + TRNG_CR);
75 trng->rng.name = pdev->name;
76 trng->rng.read = atmel_trng_read;
77
78 ret = hwrng_register(&trng->rng);
79 if (ret)
80 goto err_register;
81
82 platform_set_drvdata(pdev, trng);
83
84 return 0;
85
86err_register:
87 clk_disable(trng->clk);
88err_enable:
89 clk_put(trng->clk);
90
91 return ret;
92}
93
94static int __devexit atmel_trng_remove(struct platform_device *pdev)
95{
96 struct atmel_trng *trng = platform_get_drvdata(pdev);
97
98 hwrng_unregister(&trng->rng);
99
100 writel(TRNG_KEY, trng->base + TRNG_CR);
101 clk_disable(trng->clk);
102 clk_put(trng->clk);
103
104 platform_set_drvdata(pdev, NULL);
105
106 return 0;
107}
108
109#ifdef CONFIG_PM
110static int atmel_trng_suspend(struct device *dev)
111{
112 struct atmel_trng *trng = dev_get_drvdata(dev);
113
114 clk_disable(trng->clk);
115
116 return 0;
117}
118
119static int atmel_trng_resume(struct device *dev)
120{
121 struct atmel_trng *trng = dev_get_drvdata(dev);
122
123 return clk_enable(trng->clk);
124}
125
126static const struct dev_pm_ops atmel_trng_pm_ops = {
127 .suspend = atmel_trng_suspend,
128 .resume = atmel_trng_resume,
129};
130#endif /* CONFIG_PM */
131
132static struct platform_driver atmel_trng_driver = {
133 .probe = atmel_trng_probe,
134 .remove = __devexit_p(atmel_trng_remove),
135 .driver = {
136 .name = "atmel-trng",
137 .owner = THIS_MODULE,
138#ifdef CONFIG_PM
139 .pm = &atmel_trng_pm_ops,
140#endif /* CONFIG_PM */
141 },
142};
143
144static int __init atmel_trng_init(void)
145{
146 return platform_driver_register(&atmel_trng_driver);
147}
148module_init(atmel_trng_init);
149
150static void __exit atmel_trng_exit(void)
151{
152 platform_driver_unregister(&atmel_trng_driver);
153}
154module_exit(atmel_trng_exit);
155
156MODULE_LICENSE("GPL");
157MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
158MODULE_DESCRIPTION("Atmel true random number generator driver");