]> Git Repo - J-u-boot.git/blobdiff - drivers/tpm/tpm-uclass.c
Merge patch series "cmd: bdinfo: Optionally use getopt and implement bdinfo -a"
[J-u-boot.git] / drivers / tpm / tpm-uclass.c
index 412697eedc4d49eeddd1ae35c3fe9973c979c9d9..b2286f7e7edc842e7e25f3cac6a39714e5395348 100644 (file)
@@ -4,16 +4,21 @@
  * Written by Simon Glass <[email protected]>
  */
 
+#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);
@@ -44,6 +49,16 @@ int tpm_get_desc(struct udevice *dev, char *buf, int size)
        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)
@@ -75,7 +90,7 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
        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);
@@ -88,15 +103,15 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_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;
@@ -123,14 +138,48 @@ int tpm_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
                }
        } 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),
 };
This page took 0.029406 seconds and 4 git commands to generate.