Skip to content

Commit 5343e67

Browse files
chunkeeyherbertx
authored andcommitted
crypto4xx: integrate ppc4xx-rng into crypto4xx
This patch integrates the ppc4xx-rng driver into the existing crypto4xx. This is because the true random number generator is controlled and part of the security core. Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent e81f334 commit 5343e67

File tree

10 files changed

+184
-163
lines changed

10 files changed

+184
-163
lines changed

drivers/char/hw_random/Kconfig

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -268,19 +268,6 @@ config HW_RANDOM_NOMADIK
268268

269269
If unsure, say Y.
270270

271-
config HW_RANDOM_PPC4XX
272-
tristate "PowerPC 4xx generic true random number generator support"
273-
depends on PPC && 4xx
274-
default HW_RANDOM
275-
---help---
276-
This driver provides the kernel-side support for the TRNG hardware
277-
found in the security function of some PowerPC 4xx SoCs.
278-
279-
To compile this driver as a module, choose M here: the
280-
module will be called ppc4xx-rng.
281-
282-
If unsure, say N.
283-
284271
config HW_RANDOM_PSERIES
285272
tristate "pSeries HW Random Number Generator support"
286273
depends on PPC64 && IBMVIO

drivers/char/hw_random/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
2222
obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
2323
obj-$(CONFIG_HW_RANDOM_OCTEON) += octeon-rng.o
2424
obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
25-
obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
2625
obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
2726
obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
2827
obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o

drivers/char/hw_random/ppc4xx-rng.c

Lines changed: 0 additions & 147 deletions
This file was deleted.

drivers/crypto/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ config CRYPTO_DEV_PPC4XX
279279
help
280280
This option allows you to have support for AMCC crypto acceleration.
281281

282+
config HW_RANDOM_PPC4XX
283+
bool "PowerPC 4xx generic true random number generator support"
284+
depends on CRYPTO_DEV_PPC4XX && HW_RANDOM
285+
default y
286+
---help---
287+
This option provides the kernel-side support for the TRNG hardware
288+
found in the security function of some PowerPC 4xx SoCs.
289+
282290
config CRYPTO_DEV_OMAP_SHAM
283291
tristate "Support for OMAP MD5/SHA1/SHA2 hw accelerator"
284292
depends on ARCH_OMAP2PLUS

drivers/crypto/amcc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += crypto4xx.o
22
crypto4xx-y := crypto4xx_core.o crypto4xx_alg.o crypto4xx_sa.o
3+
crypto4xx-$(CONFIG_HW_RANDOM_PPC4XX) += crypto4xx_trng.o

drivers/crypto/amcc/crypto4xx_core.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "crypto4xx_reg_def.h"
4141
#include "crypto4xx_core.h"
4242
#include "crypto4xx_sa.h"
43+
#include "crypto4xx_trng.h"
4344

4445
#define PPC4XX_SEC_VERSION_STR "0.5"
4546

@@ -1225,6 +1226,7 @@ static int crypto4xx_probe(struct platform_device *ofdev)
12251226
if (rc)
12261227
goto err_start_dev;
12271228

1229+
ppc4xx_trng_probe(core_dev);
12281230
return 0;
12291231

12301232
err_start_dev:
@@ -1252,6 +1254,8 @@ static int crypto4xx_remove(struct platform_device *ofdev)
12521254
struct device *dev = &ofdev->dev;
12531255
struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev);
12541256

1257+
ppc4xx_trng_remove(core_dev);
1258+
12551259
free_irq(core_dev->irq, dev);
12561260
irq_dispose_mapping(core_dev->irq);
12571261

@@ -1272,7 +1276,7 @@ MODULE_DEVICE_TABLE(of, crypto4xx_match);
12721276

12731277
static struct platform_driver crypto4xx_driver = {
12741278
.driver = {
1275-
.name = "crypto4xx",
1279+
.name = MODULE_NAME,
12761280
.of_match_table = crypto4xx_match,
12771281
},
12781282
.probe = crypto4xx_probe,
@@ -1284,4 +1288,3 @@ module_platform_driver(crypto4xx_driver);
12841288
MODULE_LICENSE("GPL");
12851289
MODULE_AUTHOR("James Hsiao <jhsiao@amcc.com>");
12861290
MODULE_DESCRIPTION("Driver for AMCC PPC4xx crypto accelerator");
1287-

drivers/crypto/amcc/crypto4xx_core.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
#include <crypto/internal/hash.h>
2626

27+
#define MODULE_NAME "crypto4xx"
28+
2729
#define PPC460SX_SDR0_SRST 0x201
2830
#define PPC405EX_SDR0_SRST 0x200
2931
#define PPC460EX_SDR0_SRST 0x201
@@ -72,6 +74,7 @@ struct crypto4xx_device {
7274
char *name;
7375
u64 ce_phy_address;
7476
void __iomem *ce_base;
77+
void __iomem *trng_base;
7578

7679
void *pdr; /* base address of packet
7780
descriptor ring */
@@ -106,6 +109,7 @@ struct crypto4xx_core_device {
106109
struct device *device;
107110
struct platform_device *ofdev;
108111
struct crypto4xx_device *dev;
112+
struct hwrng *trng;
109113
u32 int_status;
110114
u32 irq;
111115
struct tasklet_struct tasklet;

drivers/crypto/amcc/crypto4xx_reg_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
#define PPC4XX_INTERRUPT_CLR 0x3ffff
126126
#define PPC4XX_PRNG_CTRL_AUTO_EN 0x3
127127
#define PPC4XX_DC_3DES_EN 1
128+
#define PPC4XX_TRNG_EN 0x00020000
128129
#define PPC4XX_INT_DESCR_CNT 4
129130
#define PPC4XX_INT_TIMEOUT_CNT 0
130131
#define PPC4XX_INT_CFG 1

drivers/crypto/amcc/crypto4xx_trng.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Generic PowerPC 44x RNG driver
3+
*
4+
* Copyright 2011 IBM Corporation
5+
*
6+
* This program is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License as published by the
8+
* Free Software Foundation; version 2 of the License.
9+
*/
10+
11+
#include <linux/module.h>
12+
#include <linux/kernel.h>
13+
#include <linux/interrupt.h>
14+
#include <linux/platform_device.h>
15+
#include <linux/hw_random.h>
16+
#include <linux/delay.h>
17+
#include <linux/of_address.h>
18+
#include <linux/of_platform.h>
19+
#include <linux/io.h>
20+
21+
#include "crypto4xx_core.h"
22+
#include "crypto4xx_trng.h"
23+
#include "crypto4xx_reg_def.h"
24+
25+
#define PPC4XX_TRNG_CTRL 0x0008
26+
#define PPC4XX_TRNG_CTRL_DALM 0x20
27+
#define PPC4XX_TRNG_STAT 0x0004
28+
#define PPC4XX_TRNG_STAT_B 0x1
29+
#define PPC4XX_TRNG_DATA 0x0000
30+
31+
static int ppc4xx_trng_data_present(struct hwrng *rng, int wait)
32+
{
33+
struct crypto4xx_device *dev = (void *)rng->priv;
34+
int busy, i, present = 0;
35+
36+
for (i = 0; i < 20; i++) {
37+
busy = (in_le32(dev->trng_base + PPC4XX_TRNG_STAT) &
38+
PPC4XX_TRNG_STAT_B);
39+
if (!busy || !wait) {
40+
present = 1;
41+
break;
42+
}
43+
udelay(10);
44+
}
45+
return present;
46+
}
47+
48+
static int ppc4xx_trng_data_read(struct hwrng *rng, u32 *data)
49+
{
50+
struct crypto4xx_device *dev = (void *)rng->priv;
51+
*data = in_le32(dev->trng_base + PPC4XX_TRNG_DATA);
52+
return 4;
53+
}
54+
55+
static void ppc4xx_trng_enable(struct crypto4xx_device *dev, bool enable)
56+
{
57+
u32 device_ctrl;
58+
59+
device_ctrl = readl(dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
60+
if (enable)
61+
device_ctrl |= PPC4XX_TRNG_EN;
62+
else
63+
device_ctrl &= ~PPC4XX_TRNG_EN;
64+
writel(device_ctrl, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
65+
}
66+
67+
static const struct of_device_id ppc4xx_trng_match[] = {
68+
{ .compatible = "ppc4xx-rng", },
69+
{ .compatible = "amcc,ppc460ex-rng", },
70+
{ .compatible = "amcc,ppc440epx-rng", },
71+
{},
72+
};
73+
74+
void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev)
75+
{
76+
struct crypto4xx_device *dev = core_dev->dev;
77+
struct device_node *trng = NULL;
78+
struct hwrng *rng = NULL;
79+
int err;
80+
81+
/* Find the TRNG device node and map it */
82+
trng = of_find_matching_node(NULL, ppc4xx_trng_match);
83+
if (!trng || !of_device_is_available(trng))
84+
return;
85+
86+
dev->trng_base = of_iomap(trng, 0);
87+
of_node_put(trng);
88+
if (!dev->trng_base)
89+
goto err_out;
90+
91+
rng = kzalloc(sizeof(*rng), GFP_KERNEL);
92+
if (!rng)
93+
goto err_out;
94+
95+
rng->name = MODULE_NAME;
96+
rng->data_present = ppc4xx_trng_data_present;
97+
rng->data_read = ppc4xx_trng_data_read;
98+
rng->priv = (unsigned long) dev;
99+
core_dev->trng = rng;
100+
ppc4xx_trng_enable(dev, true);
101+
out_le32(dev->trng_base + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
102+
err = devm_hwrng_register(core_dev->device, core_dev->trng);
103+
if (err) {
104+
ppc4xx_trng_enable(dev, false);
105+
dev_err(core_dev->device, "failed to register hwrng (%d).\n",
106+
err);
107+
goto err_out;
108+
}
109+
return;
110+
111+
err_out:
112+
of_node_put(trng);
113+
iounmap(dev->trng_base);
114+
kfree(rng);
115+
dev->trng_base = NULL;
116+
core_dev->trng = NULL;
117+
}
118+
119+
void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev)
120+
{
121+
if (core_dev && core_dev->trng) {
122+
struct crypto4xx_device *dev = core_dev->dev;
123+
124+
devm_hwrng_unregister(core_dev->device, core_dev->trng);
125+
ppc4xx_trng_enable(dev, false);
126+
iounmap(dev->trng_base);
127+
kfree(core_dev->trng);
128+
}
129+
}
130+
131+
MODULE_ALIAS("ppc4xx_rng");

0 commit comments

Comments
 (0)