tpm: Fix handling of missing event log
[platform/kernel/linux-starfive.git] / drivers / char / tpm / tpm_of.c
index 570f30c..7dee42d 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 2012 IBM Corporation
  *
  * Author: Ashley Lai <ashleydlai@gmail.com>
+ *         Nayna Jain <nayna@linux.vnet.ibm.com>
  *
  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
  *
 #include "tpm.h"
 #include "tpm_eventlog.h"
 
-int read_log(struct tpm_bios_log *log)
+int tpm_read_log_of(struct tpm_chip *chip)
 {
        struct device_node *np;
        const u32 *sizep;
        const u64 *basep;
+       struct tpm_bios_log *log;
 
-       if (log->bios_event_log != NULL) {
-               pr_err("%s: ERROR - Eventlog already initialized\n", __func__);
-               return -EFAULT;
-       }
-
-       np = of_find_node_by_name(NULL, "vtpm");
-       if (!np) {
-               pr_err("%s: ERROR - IBMVTPM not supported\n", __func__);
+       log = &chip->log;
+       if (chip->dev.parent && chip->dev.parent->of_node)
+               np = chip->dev.parent->of_node;
+       else
                return -ENODEV;
-       }
 
        sizep = of_get_property(np, "linux,sml-size", NULL);
-       if (sizep == NULL) {
-               pr_err("%s: ERROR - SML size not found\n", __func__);
-               goto cleanup_eio;
-       }
-       if (*sizep == 0) {
-               pr_err("%s: ERROR - event log area empty\n", __func__);
-               goto cleanup_eio;
-       }
-
        basep = of_get_property(np, "linux,sml-base", NULL);
-       if (basep == NULL) {
-               pr_err("%s: ERROR - SML not found\n", __func__);
-               goto cleanup_eio;
+       if (sizep == NULL && basep == NULL)
+               return -ENODEV;
+       if (sizep == NULL || basep == NULL)
+               return -EIO;
+
+       if (*sizep == 0) {
+               dev_warn(&chip->dev, "%s: Event log area empty\n", __func__);
+               return -EIO;
        }
 
        log->bios_event_log = kmalloc(*sizep, GFP_KERNEL);
-       if (!log->bios_event_log) {
-               pr_err("%s: ERROR - Not enough memory for BIOS measurements\n",
-                      __func__);
-               of_node_put(np);
+       if (!log->bios_event_log)
                return -ENOMEM;
-       }
 
        log->bios_event_log_end = log->bios_event_log + *sizep;
 
        memcpy(log->bios_event_log, __va(*basep), *sizep);
-       of_node_put(np);
 
        return 0;
-
-cleanup_eio:
-       of_node_put(np);
-       return -EIO;
 }