aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-26 16:00:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-26 16:00:59 -0400
commit44a6b8442190cf213081060b610dae2e822f802b (patch)
tree2280bfe385bef8b6416a6493ea8988a975008165 /drivers/char
parent945c40c6b007eb4b07374a38ea37b2a34da306b1 (diff)
parenta43478863b16cb0986fd2ec9d1f1b9ebaaec5922 (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/Kconfig12
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/exynos-rng.c182
-rw-r--r--drivers/char/hw_random/mxc-rnga.c21
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
267config 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
23obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o 23obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
24obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o 24obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
25obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o 25obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
26obj-$(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
40struct exynos_rng {
41 struct device *dev;
42 struct hwrng rng;
43 void __iomem *mem;
44 struct clk *clk;
45};
46
47static u32 exynos_rng_readl(struct exynos_rng *rng, u32 offset)
48{
49 return __raw_readl(rng->mem + offset);
50}
51
52static void exynos_rng_writel(struct exynos_rng *rng, u32 val, u32 offset)
53{
54 __raw_writel(val, rng->mem + offset);
55}
56
57static int exynos_init(struct hwrng *rng)
58{
59 struct exynos_rng *exynos_rng = container_of(rng,
60 struct exynos_rng, rng);
61 int i;
62 int ret = 0;
63
64 pm_runtime_get_sync(exynos_rng->dev);
65
66 for (i = 0 ; i < 5 ; i++)
67 exynos_rng_writel(exynos_rng, jiffies,
68 EXYNOS_PRNG_SEED_OFFSET + 4*i);
69
70 if (!(exynos_rng_readl(exynos_rng, EXYNOS_PRNG_STATUS_OFFSET)
71 & SEED_SETTING_DONE))
72 ret = -EIO;
73
74 pm_runtime_put_noidle(exynos_rng->dev);
75
76 return ret;
77}
78
79static int exynos_read(struct hwrng *rng, void *buf,
80 size_t max, bool wait)
81{
82 struct exynos_rng *exynos_rng = container_of(rng,
83 struct exynos_rng, rng);
84 u32 *data = buf;
85
86 pm_runtime_get_sync(exynos_rng->dev);
87
88 exynos_rng_writel(exynos_rng, PRNG_START, 0);
89
90 while (!(exynos_rng_readl(exynos_rng,
91 EXYNOS_PRNG_STATUS_OFFSET) & PRNG_DONE))
92 cpu_relax();
93
94 exynos_rng_writel(exynos_rng, PRNG_DONE, EXYNOS_PRNG_STATUS_OFFSET);
95
96 *data = exynos_rng_readl(exynos_rng, EXYNOS_PRNG_OUT1_OFFSET);
97
98 pm_runtime_mark_last_busy(exynos_rng->dev);
99 pm_runtime_autosuspend(exynos_rng->dev);
100
101 return 4;
102}
103
104static int __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
137static 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
146static int exynos_rng_runtime_suspend(struct device *dev)
147{
148 struct platform_device *pdev = to_platform_device(dev);
149 struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
150
151 clk_disable_unprepare(exynos_rng->clk);
152
153 return 0;
154}
155
156static int exynos_rng_runtime_resume(struct device *dev)
157{
158 struct platform_device *pdev = to_platform_device(dev);
159 struct exynos_rng *exynos_rng = platform_get_drvdata(pdev);
160
161 return clk_prepare_enable(exynos_rng->clk);
162}
163
164
165UNIVERSAL_DEV_PM_OPS(exynos_rng_pm_ops, exynos_rng_runtime_suspend,
166 exynos_rng_runtime_resume, NULL);
167
168static struct platform_driver exynos_rng_driver = {
169 .driver = {
170 .name = "exynos-rng",
171 .owner = THIS_MODULE,
172 .pm = &exynos_rng_pm_ops,
173 },
174 .probe = exynos_rng_probe,
175 .remove = __devexit_p(exynos_rng_remove),
176};
177
178module_platform_driver(exynos_rng_driver);
179
180MODULE_DESCRIPTION("EXYNOS 4 H/W Random Number Generator driver");
181MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>");
182MODULE_LICENSE("GPL");
diff --git a/drivers/char/hw_random/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
61static struct platform_device *rng_dev; 62static struct platform_device *rng_dev;
62 63
63static int mxc_rnga_data_present(struct hwrng *rng) 64static 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
75static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) 80static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)