324c695d05dcd183cb846a6fbe5f06dff65b042b
[openwrt/staging/stintel.git] / target / linux / apm821xx / patches-4.4 / 001-crypto4xx-integrate-ppc4xx-rng-into-crypto4xx.patch
1 From 5343e674f32fb82b7a80a24b5a84eee62d3fe624 Mon Sep 17 00:00:00 2001
2 From: Christian Lamparter <chunkeey@googlemail.com>
3 Date: Mon, 18 Apr 2016 12:57:41 +0200
4 Subject: [PATCH] crypto4xx: integrate ppc4xx-rng into crypto4xx
5
6 This patch integrates the ppc4xx-rng driver into the existing
7 crypto4xx. This is because the true random number generator
8 is controlled and part of the security core.
9
10 Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
11 Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
12 ---
13 drivers/char/hw_random/Kconfig | 13 ---
14 drivers/char/hw_random/Makefile | 1 -
15 drivers/char/hw_random/ppc4xx-rng.c | 147 --------------------------------
16 drivers/crypto/Kconfig | 8 ++
17 drivers/crypto/amcc/Makefile | 1 +
18 drivers/crypto/amcc/crypto4xx_core.c | 7 +-
19 drivers/crypto/amcc/crypto4xx_core.h | 4 +
20 drivers/crypto/amcc/crypto4xx_reg_def.h | 1 +
21 drivers/crypto/amcc/crypto4xx_trng.c | 131 ++++++++++++++++++++++++++++
22 drivers/crypto/amcc/crypto4xx_trng.h | 34 ++++++++
23 10 files changed, 184 insertions(+), 163 deletions(-)
24 delete mode 100644 drivers/char/hw_random/ppc4xx-rng.c
25 create mode 100644 drivers/crypto/amcc/crypto4xx_trng.c
26 create mode 100644 drivers/crypto/amcc/crypto4xx_trng.h
27
28 --- a/drivers/char/hw_random/Kconfig
29 +++ b/drivers/char/hw_random/Kconfig
30 @@ -268,19 +268,6 @@ config HW_RANDOM_NOMADIK
31
32 If unsure, say Y.
33
34 -config HW_RANDOM_PPC4XX
35 - tristate "PowerPC 4xx generic true random number generator support"
36 - depends on PPC && 4xx
37 - default HW_RANDOM
38 - ---help---
39 - This driver provides the kernel-side support for the TRNG hardware
40 - found in the security function of some PowerPC 4xx SoCs.
41 -
42 - To compile this driver as a module, choose M here: the
43 - module will be called ppc4xx-rng.
44 -
45 - If unsure, say N.
46 -
47 config HW_RANDOM_PSERIES
48 tristate "pSeries HW Random Number Generator support"
49 depends on PPC64 && IBMVIO
50 --- a/drivers/char/hw_random/Makefile
51 +++ b/drivers/char/hw_random/Makefile
52 @@ -22,7 +22,6 @@ obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939
53 obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
54 obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
55 obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
56 -obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
57 obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
58 obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
59 obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
60 --- a/drivers/char/hw_random/ppc4xx-rng.c
61 +++ /dev/null
62 @@ -1,147 +0,0 @@
63 -/*
64 - * Generic PowerPC 44x RNG driver
65 - *
66 - * Copyright 2011 IBM Corporation
67 - *
68 - * This program is free software; you can redistribute it and/or modify it
69 - * under the terms of the GNU General Public License as published by the
70 - * Free Software Foundation; version 2 of the License.
71 - */
72 -
73 -#include <linux/module.h>
74 -#include <linux/kernel.h>
75 -#include <linux/platform_device.h>
76 -#include <linux/hw_random.h>
77 -#include <linux/delay.h>
78 -#include <linux/of_address.h>
79 -#include <linux/of_platform.h>
80 -#include <asm/io.h>
81 -
82 -#define PPC4XX_TRNG_DEV_CTRL 0x60080
83 -
84 -#define PPC4XX_TRNGE 0x00020000
85 -#define PPC4XX_TRNG_CTRL 0x0008
86 -#define PPC4XX_TRNG_CTRL_DALM 0x20
87 -#define PPC4XX_TRNG_STAT 0x0004
88 -#define PPC4XX_TRNG_STAT_B 0x1
89 -#define PPC4XX_TRNG_DATA 0x0000
90 -
91 -#define MODULE_NAME "ppc4xx_rng"
92 -
93 -static int ppc4xx_rng_data_present(struct hwrng *rng, int wait)
94 -{
95 - void __iomem *rng_regs = (void __iomem *) rng->priv;
96 - int busy, i, present = 0;
97 -
98 - for (i = 0; i < 20; i++) {
99 - busy = (in_le32(rng_regs + PPC4XX_TRNG_STAT) & PPC4XX_TRNG_STAT_B);
100 - if (!busy || !wait) {
101 - present = 1;
102 - break;
103 - }
104 - udelay(10);
105 - }
106 - return present;
107 -}
108 -
109 -static int ppc4xx_rng_data_read(struct hwrng *rng, u32 *data)
110 -{
111 - void __iomem *rng_regs = (void __iomem *) rng->priv;
112 - *data = in_le32(rng_regs + PPC4XX_TRNG_DATA);
113 - return 4;
114 -}
115 -
116 -static int ppc4xx_rng_enable(int enable)
117 -{
118 - struct device_node *ctrl;
119 - void __iomem *ctrl_reg;
120 - int err = 0;
121 - u32 val;
122 -
123 - /* Find the main crypto device node and map it to turn the TRNG on */
124 - ctrl = of_find_compatible_node(NULL, NULL, "amcc,ppc4xx-crypto");
125 - if (!ctrl)
126 - return -ENODEV;
127 -
128 - ctrl_reg = of_iomap(ctrl, 0);
129 - if (!ctrl_reg) {
130 - err = -ENODEV;
131 - goto out;
132 - }
133 -
134 - val = in_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL);
135 -
136 - if (enable)
137 - val |= PPC4XX_TRNGE;
138 - else
139 - val = val & ~PPC4XX_TRNGE;
140 -
141 - out_le32(ctrl_reg + PPC4XX_TRNG_DEV_CTRL, val);
142 - iounmap(ctrl_reg);
143 -
144 -out:
145 - of_node_put(ctrl);
146 -
147 - return err;
148 -}
149 -
150 -static struct hwrng ppc4xx_rng = {
151 - .name = MODULE_NAME,
152 - .data_present = ppc4xx_rng_data_present,
153 - .data_read = ppc4xx_rng_data_read,
154 -};
155 -
156 -static int ppc4xx_rng_probe(struct platform_device *dev)
157 -{
158 - void __iomem *rng_regs;
159 - int err = 0;
160 -
161 - rng_regs = of_iomap(dev->dev.of_node, 0);
162 - if (!rng_regs)
163 - return -ENODEV;
164 -
165 - err = ppc4xx_rng_enable(1);
166 - if (err)
167 - return err;
168 -
169 - out_le32(rng_regs + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
170 - ppc4xx_rng.priv = (unsigned long) rng_regs;
171 -
172 - err = hwrng_register(&ppc4xx_rng);
173 -
174 - return err;
175 -}
176 -
177 -static int ppc4xx_rng_remove(struct platform_device *dev)
178 -{
179 - void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv;
180 -
181 - hwrng_unregister(&ppc4xx_rng);
182 - ppc4xx_rng_enable(0);
183 - iounmap(rng_regs);
184 -
185 - return 0;
186 -}
187 -
188 -static const struct of_device_id ppc4xx_rng_match[] = {
189 - { .compatible = "ppc4xx-rng", },
190 - { .compatible = "amcc,ppc460ex-rng", },
191 - { .compatible = "amcc,ppc440epx-rng", },
192 - {},
193 -};
194 -MODULE_DEVICE_TABLE(of, ppc4xx_rng_match);
195 -
196 -static struct platform_driver ppc4xx_rng_driver = {
197 - .driver = {
198 - .name = MODULE_NAME,
199 - .of_match_table = ppc4xx_rng_match,
200 - },
201 - .probe = ppc4xx_rng_probe,
202 - .remove = ppc4xx_rng_remove,
203 -};
204 -
205 -module_platform_driver(ppc4xx_rng_driver);
206 -
207 -MODULE_LICENSE("GPL");
208 -MODULE_AUTHOR("Josh Boyer <jwboyer@linux.vnet.ibm.com>");
209 -MODULE_DESCRIPTION("HW RNG driver for PPC 4xx processors");
210 --- a/drivers/crypto/Kconfig
211 +++ b/drivers/crypto/Kconfig
212 @@ -277,6 +277,14 @@ config CRYPTO_DEV_PPC4XX
213 help
214 This option allows you to have support for AMCC crypto acceleration.
215
216 +config HW_RANDOM_PPC4XX
217 + bool "PowerPC 4xx generic true random number generator support"
218 + depends on CRYPTO_DEV_PPC4XX && HW_RANDOM
219 + default y
220 + ---help---
221 + This option provides the kernel-side support for the TRNG hardware
222 + found in the security function of some PowerPC 4xx SoCs.
223 +
224 config CRYPTO_DEV_OMAP_SHAM
225 tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator"
226 depends on ARCH_OMAP2PLUS
227 --- a/drivers/crypto/amcc/Makefile
228 +++ b/drivers/crypto/amcc/Makefile
229 @@ -1,2 +1,3 @@
230 obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
231 crypto4xx-y := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
232 +crypto4xx-$(CONFIG_HW_RANDOM_PPC4XX) += crypto4xx_trng.o
233 --- a/drivers/crypto/amcc/crypto4xx_core.c
234 +++ b/drivers/crypto/amcc/crypto4xx_core.c
235 @@ -40,6 +40,7 @@
236 #include "crypto4xx_reg_def.h"
237 #include "crypto4xx_core.h"
238 #include "crypto4xx_sa.h"
239 +#include "crypto4xx_trng.h"
240
241 #define PPC4XX_SEC_VERSION_STR "0.5"
242
243 @@ -1221,6 +1222,7 @@ static int crypto4xx_probe(struct platfo
244 if (rc)
245 goto err_start_dev;
246
247 + ppc4xx_trng_probe(core_dev);
248 return 0;
249
250 err_start_dev:
251 @@ -1248,6 +1250,8 @@ static int crypto4xx_remove(struct platf
252 struct device *dev = &ofdev->dev;
253 struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
254
255 + ppc4xx_trng_remove(core_dev);
256 +
257 free_irq(core_dev->irq, dev);
258 irq_dispose_mapping(core_dev->irq);
259
260 @@ -1268,7 +1272,7 @@ MODULE_DEVICE_TABLE(of, crypto4xx_match)
261
262 static struct platform_driver crypto4xx_driver = {
263 .driver = {
264 - .name = "crypto4xx",
265 + .name = MODULE_NAME,
266 .of_match_table = crypto4xx_match,
267 },
268 .probe = crypto4xx_probe,
269 @@ -1280,4 +1284,3 @@ module_platform_driver(crypto4xx_driver)
270 MODULE_LICENSE("GPL");
271 MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
272 MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator");
273 -
274 --- a/drivers/crypto/amcc/crypto4xx_core.h
275 +++ b/drivers/crypto/amcc/crypto4xx_core.h
276 @@ -24,6 +24,8 @@
277
278 #include <crypto/internal/hash.h>
279
280 +#define MODULE_NAME "crypto4xx"
281 +
282 #define PPC460SX_SDR0_SRST 0x201
283 #define PPC405EX_SDR0_SRST 0x200
284 #define PPC460EX_SDR0_SRST 0x201
285 @@ -72,6 +74,7 @@ struct crypto4xx_device {
286 char *name;
287 u64 ce_phy_address;
288 void __iomem *ce_base;
289 + void __iomem *trng_base;
290
291 void *pdr; /* base address of packet
292 descriptor ring */
293 @@ -106,6 +109,7 @@ struct crypto4xx_core_device {
294 struct device *device;
295 struct platform_device *ofdev;
296 struct crypto4xx_device *dev;
297 + struct hwrng *trng;
298 u32 int_status;
299 u32 irq;
300 struct tasklet_struct tasklet;
301 --- a/drivers/crypto/amcc/crypto4xx_reg_def.h
302 +++ b/drivers/crypto/amcc/crypto4xx_reg_def.h
303 @@ -125,6 +125,7 @@
304 #define PPC4XX_INTERRUPT_CLR 0x3ffff
305 #define PPC4XX_PRNG_CTRL_AUTO_EN 0x3
306 #define PPC4XX_DC_3DES_EN 1
307 +#define PPC4XX_TRNG_EN 0x00020000
308 #define PPC4XX_INT_DESCR_CNT 4
309 #define PPC4XX_INT_TIMEOUT_CNT 0
310 #define PPC4XX_INT_CFG 1
311 --- /dev/null
312 +++ b/drivers/crypto/amcc/crypto4xx_trng.c
313 @@ -0,0 +1,131 @@
314 +/*
315 + * Generic PowerPC 44x RNG driver
316 + *
317 + * Copyright 2011 IBM Corporation
318 + *
319 + * This program is free software; you can redistribute it and/or modify it
320 + * under the terms of the GNU General Public License as published by the
321 + * Free Software Foundation; version 2 of the License.
322 + */
323 +
324 +#include <linux/module.h>
325 +#include <linux/kernel.h>
326 +#include <linux/interrupt.h>
327 +#include <linux/platform_device.h>
328 +#include <linux/hw_random.h>
329 +#include <linux/delay.h>
330 +#include <linux/of_address.h>
331 +#include <linux/of_platform.h>
332 +#include <linux/io.h>
333 +
334 +#include "crypto4xx_core.h"
335 +#include "crypto4xx_trng.h"
336 +#include "crypto4xx_reg_def.h"
337 +
338 +#define PPC4XX_TRNG_CTRL 0x0008
339 +#define PPC4XX_TRNG_CTRL_DALM 0x20
340 +#define PPC4XX_TRNG_STAT 0x0004
341 +#define PPC4XX_TRNG_STAT_B 0x1
342 +#define PPC4XX_TRNG_DATA 0x0000
343 +
344 +static int ppc4xx_trng_data_present(struct hwrng *rng, int wait)
345 +{
346 + struct crypto4xx_device *dev = (void *)rng->priv;
347 + int busy, i, present = 0;
348 +
349 + for (i = 0; i < 20; i++) {
350 + busy = (in_le32(dev->trng_base + PPC4XX_TRNG_STAT) &
351 + PPC4XX_TRNG_STAT_B);
352 + if (!busy || !wait) {
353 + present = 1;
354 + break;
355 + }
356 + udelay(10);
357 + }
358 + return present;
359 +}
360 +
361 +static int ppc4xx_trng_data_read(struct hwrng *rng, u32 *data)
362 +{
363 + struct crypto4xx_device *dev = (void *)rng->priv;
364 + *data = in_le32(dev->trng_base + PPC4XX_TRNG_DATA);
365 + return 4;
366 +}
367 +
368 +static void ppc4xx_trng_enable(struct crypto4xx_device *dev, bool enable)
369 +{
370 + u32 device_ctrl;
371 +
372 + device_ctrl = readl(dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
373 + if (enable)
374 + device_ctrl |= PPC4XX_TRNG_EN;
375 + else
376 + device_ctrl &= ~PPC4XX_TRNG_EN;
377 + writel(device_ctrl, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
378 +}
379 +
380 +static const struct of_device_id ppc4xx_trng_match[] = {
381 + { .compatible = "ppc4xx-rng", },
382 + { .compatible = "amcc,ppc460ex-rng", },
383 + { .compatible = "amcc,ppc440epx-rng", },
384 + {},
385 +};
386 +
387 +void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev)
388 +{
389 + struct crypto4xx_device *dev = core_dev->dev;
390 + struct device_node *trng = NULL;
391 + struct hwrng *rng = NULL;
392 + int err;
393 +
394 + /* Find the TRNG device node and map it */
395 + trng = of_find_matching_node(NULL, ppc4xx_trng_match);
396 + if (!trng || !of_device_is_available(trng))
397 + return;
398 +
399 + dev->trng_base = of_iomap(trng, 0);
400 + of_node_put(trng);
401 + if (!dev->trng_base)
402 + goto err_out;
403 +
404 + rng = kzalloc(sizeof(*rng), GFP_KERNEL);
405 + if (!rng)
406 + goto err_out;
407 +
408 + rng->name = MODULE_NAME;
409 + rng->data_present = ppc4xx_trng_data_present;
410 + rng->data_read = ppc4xx_trng_data_read;
411 + rng->priv = (unsigned long) dev;
412 + core_dev->trng = rng;
413 + ppc4xx_trng_enable(dev, true);
414 + out_le32(dev->trng_base + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
415 + err = devm_hwrng_register(core_dev->device, core_dev->trng);
416 + if (err) {
417 + ppc4xx_trng_enable(dev, false);
418 + dev_err(core_dev->device, "failed to register hwrng (%d).\n",
419 + err);
420 + goto err_out;
421 + }
422 + return;
423 +
424 +err_out:
425 + of_node_put(trng);
426 + iounmap(dev->trng_base);
427 + kfree(rng);
428 + dev->trng_base = NULL;
429 + core_dev->trng = NULL;
430 +}
431 +
432 +void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev)
433 +{
434 + if (core_dev && core_dev->trng) {
435 + struct crypto4xx_device *dev = core_dev->dev;
436 +
437 + devm_hwrng_unregister(core_dev->device, core_dev->trng);
438 + ppc4xx_trng_enable(dev, false);
439 + iounmap(dev->trng_base);
440 + kfree(core_dev->trng);
441 + }
442 +}
443 +
444 +MODULE_ALIAS("ppc4xx_rng");
445 --- /dev/null
446 +++ b/drivers/crypto/amcc/crypto4xx_trng.h
447 @@ -0,0 +1,34 @@
448 +/**
449 + * AMCC SoC PPC4xx Crypto Driver
450 + *
451 + * Copyright (c) 2008 Applied Micro Circuits Corporation.
452 + * All rights reserved. James Hsiao <jhsiao@amcc.com>
453 + *
454 + * This program is free software; you can redistribute it and/or modify
455 + * it under the terms of the GNU General Public License as published by
456 + * the Free Software Foundation; either version 2 of the License, or
457 + * (at your option) any later version.
458 + *
459 + * This program is distributed in the hope that it will be useful,
460 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
461 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
462 + * GNU General Public License for more details.
463 + *
464 + * This file defines the security context
465 + * associate format.
466 + */
467 +
468 +#ifndef __CRYPTO4XX_TRNG_H__
469 +#define __CRYPTO4XX_TRNG_H__
470 +
471 +#ifdef CONFIG_HW_RANDOM_PPC4XX
472 +void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev);
473 +void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev);
474 +#else
475 +static inline void ppc4xx_trng_probe(
476 + struct crypto4xx_device *dev __maybe_unused) { }
477 +static inline void ppc4xx_trng_remove(
478 + struct crypto4xx_device *dev __maybe_unused) { }
479 +#endif
480 +
481 +#endif