diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 16:00:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-26 16:00:59 -0400 |
commit | 44a6b8442190cf213081060b610dae2e822f802b (patch) | |
tree | 2280bfe385bef8b6416a6493ea8988a975008165 /drivers/char | |
parent | 945c40c6b007eb4b07374a38ea37b2a34da306b1 (diff) | |
parent | a43478863b16cb0986fd2ec9d1f1b9ebaaec5922 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
- Fixed algorithm construction hang when self-test fails.
- Added SHA variants to talitos AEAD list.
- New driver for Exynos random number generator.
- Performance enhancements for arc4.
- Added hwrng support to caam.
- Added ahash support to caam.
- Fixed bad kfree in aesni-intel.
- Allow aesni-intel in FIPS mode.
- Added atmel driver with support for AES/3DES/SHA.
- Bug fixes for mv_cesa.
- CRC hardware driver for BF60x family processors.
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (66 commits)
crypto: twofish-avx - remove useless instruction
crypto: testmgr - add aead cbc aes hmac sha1,256,512 test vectors
crypto: talitos - add sha224, sha384 and sha512 to existing AEAD algorithms
crypto: talitos - export the talitos_submit function
crypto: talitos - move talitos structures to header file
crypto: atmel - add new tests to tcrypt
crypto: atmel - add Atmel SHA1/SHA256 driver
crypto: atmel - add Atmel DES/TDES driver
crypto: atmel - add Atmel AES driver
ARM: AT91SAM9G45: add crypto peripherals
crypto: testmgr - allow aesni-intel and ghash_clmulni-intel in fips mode
hwrng: exynos - Add support for Exynos random number generator
crypto: aesni-intel - fix wrong kfree pointer
crypto: caam - ERA retrieval and printing for SEC device
crypto: caam - Using alloc_coherent for caam job rings
crypto: algapi - Fix hang on crypto allocation
crypto: arc4 - now arc needs blockcipher support
crypto: caam - one tasklet per job ring
crypto: caam - consolidate memory barriers from job ring en/dequeue
crypto: caam - only query h/w in job ring dequeue path
...
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/hw_random/Kconfig | 12 | ||||
-rw-r--r-- | drivers/char/hw_random/Makefile | 1 | ||||
-rw-r--r-- | drivers/char/hw_random/exynos-rng.c | 182 | ||||
-rw-r--r-- | drivers/char/hw_random/mxc-rnga.c | 21 |
4 files changed, 208 insertions, 8 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index f45dad39a18b..b01d67328243 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -263,3 +263,15 @@ config HW_RANDOM_PSERIES | |||
263 | module will be called pseries-rng. | 263 | module will be called pseries-rng. |
264 | 264 | ||
265 | If unsure, say Y. | 265 | If unsure, say Y. |
266 | |||
267 | config HW_RANDOM_EXYNOS | ||
268 | tristate "EXYNOS HW random number generator support" | ||
269 | depends on HW_RANDOM && HAS_IOMEM && HAVE_CLK | ||
270 | ---help--- | ||
271 | This driver provides kernel-side support for the Random Number | ||
272 | Generator hardware found on EXYNOS SOCs. | ||
273 | |||
274 | To compile this driver as a module, choose M here: the | ||
275 | module will be called exynos-rng. | ||
276 | |||
277 | If unsure, say Y. | ||
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index d901dfa30321..8d6d173b65e6 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile | |||
@@ -23,3 +23,4 @@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o | |||
23 | obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o | 23 | obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o |
24 | obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o | 24 | obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o |
25 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o | 25 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o |
26 | obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o | ||
diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c new file mode 100644 index 000000000000..232ba9ce579c --- /dev/null +++ b/drivers/char/hw_random/exynos-rng.c | |||
@@ -0,0 +1,182 @@ | |||
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 __devinit 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 __devexit 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 = __devexit_p(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/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index 187c6be80f43..85074de5042e 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c | |||
@@ -24,6 +24,7 @@ | |||
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> | ||
27 | #include <linux/io.h> | 28 | #include <linux/io.h> |
28 | 29 | ||
29 | /* RNGA Registers */ | 30 | /* RNGA Registers */ |
@@ -60,16 +61,20 @@ | |||
60 | 61 | ||
61 | static struct platform_device *rng_dev; | 62 | static struct platform_device *rng_dev; |
62 | 63 | ||
63 | static int mxc_rnga_data_present(struct hwrng *rng) | 64 | static int mxc_rnga_data_present(struct hwrng *rng, int wait) |
64 | { | 65 | { |
65 | int level; | ||
66 | void __iomem *rng_base = (void __iomem *)rng->priv; | 66 | void __iomem *rng_base = (void __iomem *)rng->priv; |
67 | 67 | int i; | |
68 | /* how many random numbers is in FIFO? [0-16] */ | 68 | |
69 | level = ((__raw_readl(rng_base + RNGA_STATUS) & | 69 | for (i = 0; i < 20; i++) { |
70 | RNGA_STATUS_LEVEL_MASK) >> 8); | 70 | /* how many random numbers are in FIFO? [0-16] */ |
71 | 71 | int level = (__raw_readl(rng_base + RNGA_STATUS) & | |
72 | return level > 0 ? 1 : 0; | 72 | RNGA_STATUS_LEVEL_MASK) >> 8; |
73 | if (level || !wait) | ||
74 | return !!level; | ||
75 | udelay(10); | ||
76 | } | ||
77 | return 0; | ||
73 | } | 78 | } |
74 | 79 | ||
75 | static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) | 80 | static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) |