*/
+#define LOG_CATEGORY UCLASS_TPM
+
#include <common.h>
#include <dm.h>
-#include <linux/unaligned/be_byteshift.h>
-#if defined(CONFIG_TPM_V1)
+#include <log.h>
+#include <tpm_api.h>
#include <tpm-v1.h>
-#elif defined(CONFIG_TPM_V2)
#include <tpm-v2.h>
-#endif
+#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);
return ops->get_desc(dev, buf, size);
}
+int tpm_report_state(struct udevice *dev, char *buf, int size)
+{
+ struct tpm_ops *ops = tpm_get_ops(dev);
+
+ if (!ops->report_state)
+ return -ENOSYS;
+
+ return ops->report_state(dev, buf, size);
+}
+
/* Returns max number of milliseconds to wait */
static ulong tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip_priv *priv,
u32 ordinal)
struct tpm_ops *ops = tpm_get_ops(dev);
ulong start, stop;
uint count, ordinal;
- int ret, ret2;
+ int ret, ret2 = 0;
if (ops->xfer)
return ops->xfer(dev, sendbuf, send_size, recvbuf, recv_size);
ordinal = get_unaligned_be32(sendbuf + TPM_CMD_ORDINAL_BYTE);
if (count == 0) {
- debug("no data\n");
+ log_debug("no data\n");
return -ENODATA;
}
if (count > send_size) {
- debug("invalid count value %x %zx\n", count, send_size);
+ log_debug("invalid count value %x %zx\n", count, send_size);
return -E2BIG;
}
- debug("%s: Calling send\n", __func__);
+ log_debug("%s: Calling send\n", __func__);
ret = ops->send(dev, sendbuf, send_size);
if (ret < 0)
return ret;
}
} while (ret);
- ret2 = ops->cleanup ? ops->cleanup(dev) : 0;
+ if (ret) {
+ if (ops->cleanup) {
+ ret2 = ops->cleanup(dev);
+ if (ret2)
+ return log_msg_ret("cleanup", ret2);
+ }
+ return log_msg_ret("xfer", ret);
+ }
+
+ return 0;
+}
+
+static int tpm_uclass_post_probe(struct udevice *dev)
+{
+ int ret;
+ const char *drv = TPM_RNG_DRV_NAME;
+ struct udevice *child;
+
+ if (IS_ENABLED(CONFIG_TPM_RNG)) {
+ ret = device_find_first_child_by_uclass(dev, UCLASS_RNG,
+ &child);
- return ret2 ? ret2 : ret;
+ 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,
- .per_device_auto_alloc_size = sizeof(struct tpm_chip_priv),
+ .id = UCLASS_TPM,
+ .name = "tpm",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+#if CONFIG_IS_ENABLED(OF_REAL)
+ .post_bind = dm_scan_fdt_dev,
+#endif
+ .post_probe = tpm_uclass_post_probe,
+ .per_device_auto = sizeof(struct tpm_chip_priv),
};