aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rng/Kconfig9
-rw-r--r--drivers/rng/Makefile1
-rw-r--r--drivers/rng/tpm_rng.c23
-rw-r--r--drivers/tpm/tpm-uclass.c40
4 files changed, 67 insertions, 6 deletions
diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index 21a9ff0195..16143681da 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -74,4 +74,13 @@ config RNG_SMCCC_TRNG
Enable random number generator for platforms that support Arm
SMCCC TRNG interface.
+config TPM_RNG
+ bool "Enable random number generator on TPM device"
+ depends on TPM
+ default y
+ help
+ The TPM device has an inbuilt random number generator
+ functionality. Enable random number generator on TPM
+ devices.
+
endif
diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
index 2494717d7c..78f61051ac 100644
--- a/drivers/rng/Makefile
+++ b/drivers/rng/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
obj-$(CONFIG_RNG_SMCCC_TRNG) += smccc_trng.o
+obj-$(CONFIG_TPM_RNG) += tpm_rng.o
diff --git a/drivers/rng/tpm_rng.c b/drivers/rng/tpm_rng.c
new file mode 100644
index 0000000000..1a5e9e2e4b
--- /dev/null
+++ b/drivers/rng/tpm_rng.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022, Linaro Limited
+ */
+
+#include <dm.h>
+#include <rng.h>
+#include <tpm_api.h>
+
+static int rng_tpm_random_read(struct udevice *dev, void *data, size_t count)
+{
+ return tpm_get_random(dev_get_parent(dev), data, count);
+}
+
+static const struct dm_rng_ops tpm_rng_ops = {
+ .read = rng_tpm_random_read,
+};
+
+U_BOOT_DRIVER(tpm_rng) = {
+ .name = "tpm-rng",
+ .id = UCLASS_RNG,
+ .ops = &tpm_rng_ops,
+};
diff --git a/drivers/tpm/tpm-uclass.c b/drivers/tpm/tpm-uclass.c
index f67fe1019b..0eb35f50c4 100644
--- a/drivers/tpm/tpm-uclass.c
+++ b/drivers/tpm/tpm-uclass.c
@@ -9,12 +9,16 @@
#include <common.h>
#include <dm.h>
#include <log.h>
-#include <linux/delay.h>
-#include <linux/unaligned/be_byteshift.h>
+#include <tpm_api.h>
#include <tpm-v1.h>
#include <tpm-v2.h>
+#include <dm/lists.h>
+#include <linux/delay.h>
+#include <linux/unaligned/be_byteshift.h>
#include "tpm_internal.h"
+#define TPM_RNG_DRV_NAME "tpm-rng"
+
int tpm_open(struct udevice *dev)
{
struct tpm_ops *ops = tpm_get_ops(dev);
@@ -136,12 +140,36 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
return 0;
}
+static int tpm_uclass_post_probe(struct udevice *dev)
+{
+ int ret;
+ const char *drv = TPM_RNG_DRV_NAME;
+ struct udevice *child;
+
+ if (CONFIG_IS_ENABLED(TPM_RNG)) {
+ ret = device_find_first_child_by_uclass(dev, UCLASS_RNG,
+ &child);
+
+ if (ret != -ENODEV) {
+ log_debug("RNG child already added to the TPM device\n");
+ return ret;
+ }
+
+ ret = device_bind_driver(dev, drv, TPM_RNG_DRV_NAME, &child);
+ if (ret)
+ return log_msg_ret("bind", ret);
+ }
+
+ return 0;
+}
+
UCLASS_DRIVER(tpm) = {
- .id = UCLASS_TPM,
- .name = "tpm",
- .flags = DM_UC_FLAG_SEQ_ALIAS,
+ .id = UCLASS_TPM,
+ .name = "tpm",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
#if CONFIG_IS_ENABLED(OF_REAL)
- .post_bind = dm_scan_fdt_dev,
+ .post_bind = dm_scan_fdt_dev,
#endif
+ .post_probe = tpm_uclass_post_probe,
.per_device_auto = sizeof(struct tpm_chip_priv),
};