1 // SPDX-License-Identifier: GPL-2.0-only
3 * Generic PowerPC 44x RNG driver
5 * Copyright 2011 IBM Corporation
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/interrupt.h>
11 #include <linux/platform_device.h>
12 #include <linux/hw_random.h>
13 #include <linux/delay.h>
14 #include <linux/of_address.h>
15 #include <linux/of_platform.h>
18 #include "crypto4xx_core.h"
19 #include "crypto4xx_trng.h"
20 #include "crypto4xx_reg_def.h"
22 #define PPC4XX_TRNG_CTRL 0x0008
23 #define PPC4XX_TRNG_CTRL_DALM 0x20
24 #define PPC4XX_TRNG_STAT 0x0004
25 #define PPC4XX_TRNG_STAT_B 0x1
26 #define PPC4XX_TRNG_DATA 0x0000
28 static int ppc4xx_trng_data_present(struct hwrng
*rng
, int wait
)
30 struct crypto4xx_device
*dev
= (void *)rng
->priv
;
31 int busy
, i
, present
= 0;
33 for (i
= 0; i
< 20; i
++) {
34 busy
= (in_le32(dev
->trng_base
+ PPC4XX_TRNG_STAT
) &
45 static int ppc4xx_trng_data_read(struct hwrng
*rng
, u32
*data
)
47 struct crypto4xx_device
*dev
= (void *)rng
->priv
;
48 *data
= in_le32(dev
->trng_base
+ PPC4XX_TRNG_DATA
);
52 static void ppc4xx_trng_enable(struct crypto4xx_device
*dev
, bool enable
)
56 device_ctrl
= readl(dev
->ce_base
+ CRYPTO4XX_DEVICE_CTRL
);
58 device_ctrl
|= PPC4XX_TRNG_EN
;
60 device_ctrl
&= ~PPC4XX_TRNG_EN
;
61 writel(device_ctrl
, dev
->ce_base
+ CRYPTO4XX_DEVICE_CTRL
);
64 static const struct of_device_id ppc4xx_trng_match
[] = {
65 { .compatible
= "ppc4xx-rng", },
66 { .compatible
= "amcc,ppc460ex-rng", },
67 { .compatible
= "amcc,ppc440epx-rng", },
71 void ppc4xx_trng_probe(struct crypto4xx_core_device
*core_dev
)
73 struct crypto4xx_device
*dev
= core_dev
->dev
;
74 struct device_node
*trng
= NULL
;
75 struct hwrng
*rng
= NULL
;
78 /* Find the TRNG device node and map it */
79 trng
= of_find_matching_node(NULL
, ppc4xx_trng_match
);
80 if (!trng
|| !of_device_is_available(trng
)) {
85 dev
->trng_base
= of_iomap(trng
, 0);
90 rng
= kzalloc(sizeof(*rng
), GFP_KERNEL
);
94 rng
->name
= KBUILD_MODNAME
;
95 rng
->data_present
= ppc4xx_trng_data_present
;
96 rng
->data_read
= ppc4xx_trng_data_read
;
97 rng
->priv
= (unsigned long) dev
;
99 ppc4xx_trng_enable(dev
, true);
100 out_le32(dev
->trng_base
+ PPC4XX_TRNG_CTRL
, PPC4XX_TRNG_CTRL_DALM
);
101 err
= devm_hwrng_register(core_dev
->device
, core_dev
->trng
);
103 ppc4xx_trng_enable(dev
, false);
104 dev_err(core_dev
->device
, "failed to register hwrng (%d).\n",
111 iounmap(dev
->trng_base
);
113 dev
->trng_base
= NULL
;
114 core_dev
->trng
= NULL
;
117 void ppc4xx_trng_remove(struct crypto4xx_core_device
*core_dev
)
119 if (core_dev
&& core_dev
->trng
) {
120 struct crypto4xx_device
*dev
= core_dev
->dev
;
122 devm_hwrng_unregister(core_dev
->device
, core_dev
->trng
);
123 ppc4xx_trng_enable(dev
, false);
124 iounmap(dev
->trng_base
);
125 kfree(core_dev
->trng
);
129 MODULE_ALIAS("ppc4xx_rng");