001-crypto4xx-integrate-ppc4xx-rng-into-crypto4xx.patch 13 KB

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