kernel: update kernel 4.4 to version 4.4.19
[lede.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