tpm: use tpm_pcr_read_dev() in tpm_do_selftest()
[cascardo/linux.git] / drivers / char / tpm / tpm-interface.c
index e2fa89c..3edf2e8 100644 (file)
@@ -319,7 +319,7 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
                duration_idx = tpm_ordinal_duration[ordinal];
 
        if (duration_idx != TPM_UNDEFINED)
-               duration = chip->vendor.duration[duration_idx];
+               duration = chip->duration[duration_idx];
        if (duration <= 0)
                return 2 * 60 * HZ;
        else
@@ -330,8 +330,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 /*
  * Internal kernel interface to transmit TPM commands
  */
-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
-                    size_t bufsiz)
+ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
+                    unsigned int flags)
 {
        ssize_t rc;
        u32 count, ordinal;
@@ -345,21 +345,22 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
        if (count == 0)
                return -ENODATA;
        if (count > bufsiz) {
-               dev_err(chip->pdev,
+               dev_err(&chip->dev,
                        "invalid count value %x %zx\n", count, bufsiz);
                return -E2BIG;
        }
 
-       mutex_lock(&chip->tpm_mutex);
+       if (!(flags & TPM_TRANSMIT_UNLOCKED))
+               mutex_lock(&chip->tpm_mutex);
 
        rc = chip->ops->send(chip, (u8 *) buf, count);
        if (rc < 0) {
-               dev_err(chip->pdev,
+               dev_err(&chip->dev,
                        "tpm_transmit: tpm_send: error %zd\n", rc);
                goto out;
        }
 
-       if (chip->vendor.irq)
+       if (chip->flags & TPM_CHIP_FLAG_IRQ)
                goto out_recv;
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2)
@@ -373,7 +374,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                        goto out_recv;
 
                if (chip->ops->req_canceled(chip, status)) {
-                       dev_err(chip->pdev, "Operation Canceled\n");
+                       dev_err(&chip->dev, "Operation Canceled\n");
                        rc = -ECANCELED;
                        goto out;
                }
@@ -383,30 +384,31 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
        } while (time_before(jiffies, stop));
 
        chip->ops->cancel(chip);
-       dev_err(chip->pdev, "Operation Timed out\n");
+       dev_err(&chip->dev, "Operation Timed out\n");
        rc = -ETIME;
        goto out;
 
 out_recv:
        rc = chip->ops->recv(chip, (u8 *) buf, bufsiz);
        if (rc < 0)
-               dev_err(chip->pdev,
+               dev_err(&chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
 out:
-       mutex_unlock(&chip->tpm_mutex);
+       if (!(flags & TPM_TRANSMIT_UNLOCKED))
+               mutex_unlock(&chip->tpm_mutex);
        return rc;
 }
 
 #define TPM_DIGEST_SIZE 20
 #define TPM_RET_CODE_IDX 6
 
-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
-                        int len, const char *desc)
+ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd,
+                        int len, unsigned int flags, const char *desc)
 {
-       struct tpm_output_header *header;
+       const struct tpm_output_header *header;
        int err;
 
-       len = tpm_transmit(chip, (u8 *) cmd, len);
+       len = tpm_transmit(chip, (const u8 *)cmd, len, flags);
        if (len <  0)
                return len;
        else if (len < TPM_HEADER_SIZE)
@@ -416,7 +418,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
 
        err = be32_to_cpu(header->return_code);
        if (err != 0 && desc)
-               dev_err(chip->pdev, "A TPM error (%d) occurred %s\n", err,
+               dev_err(&chip->dev, "A TPM error (%d) occurred %s\n", err,
                        desc);
 
        return err;
@@ -432,12 +434,11 @@ static const struct tpm_input_header tpm_getcap_header = {
        .ordinal = TPM_ORD_GET_CAP
 };
 
-ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
+ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
                   const char *desc)
 {
        struct tpm_cmd_t tpm_cmd;
        int rc;
-       struct tpm_chip *chip = dev_get_drvdata(dev);
 
        tpm_cmd.header.in = tpm_getcap_header;
        if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
@@ -454,26 +455,13 @@ ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
                tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
                tpm_cmd.params.getcap_in.subcap = subcap_id;
        }
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
+       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+                             desc);
        if (!rc)
                *cap = tpm_cmd.params.getcap_out.cap;
        return rc;
 }
-
-void tpm_gen_interrupt(struct tpm_chip *chip)
-{
-       struct  tpm_cmd_t tpm_cmd;
-       ssize_t rc;
-
-       tpm_cmd.header.in = tpm_getcap_header;
-       tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
-       tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
-       tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
-
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
-                             "attempting to determine the timeouts");
-}
-EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+EXPORT_SYMBOL_GPL(tpm_getcap);
 
 #define TPM_ORD_STARTUP cpu_to_be32(153)
 #define TPM_ST_CLEAR cpu_to_be16(1)
@@ -491,7 +479,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
        start_cmd.header.in = tpm_startup_header;
 
        start_cmd.params.startup_in.startup_type = startup_type;
-       return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
+       return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
                                "attempting to start the TPM");
 }
 
@@ -505,15 +493,15 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                /* Fixed timeouts for TPM2 */
-               chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
-               chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
-               chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
-               chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
-               chip->vendor.duration[TPM_SHORT] =
+               chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
+               chip->timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B);
+               chip->timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C);
+               chip->timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D);
+               chip->duration[TPM_SHORT] =
                    msecs_to_jiffies(TPM2_DURATION_SHORT);
-               chip->vendor.duration[TPM_MEDIUM] =
+               chip->duration[TPM_MEDIUM] =
                    msecs_to_jiffies(TPM2_DURATION_MEDIUM);
-               chip->vendor.duration[TPM_LONG] =
+               chip->duration[TPM_LONG] =
                    msecs_to_jiffies(TPM2_DURATION_LONG);
                return 0;
        }
@@ -522,12 +510,13 @@ int tpm_get_timeouts(struct tpm_chip *chip)
        tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
        tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
        tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL);
+       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+                             NULL);
 
        if (rc == TPM_ERR_INVALID_POSTINIT) {
                /* The TPM is not started, we are the first to talk to it.
                   Execute a startup command. */
-               dev_info(chip->pdev, "Issuing TPM_STARTUP");
+               dev_info(&chip->dev, "Issuing TPM_STARTUP");
                if (tpm_startup(chip, TPM_ST_CLEAR))
                        return rc;
 
@@ -536,10 +525,10 @@ int tpm_get_timeouts(struct tpm_chip *chip)
                tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
                tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
                rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
-                                 NULL);
+                                     0, NULL);
        }
        if (rc) {
-               dev_err(chip->pdev,
+               dev_err(&chip->dev,
                        "A TPM error (%zd) occurred attempting to determine the timeouts\n",
                        rc);
                goto duration;
@@ -561,10 +550,10 @@ int tpm_get_timeouts(struct tpm_chip *chip)
         * of misreporting.
         */
        if (chip->ops->update_timeouts != NULL)
-               chip->vendor.timeout_adjusted =
+               chip->timeout_adjusted =
                        chip->ops->update_timeouts(chip, new_timeout);
 
-       if (!chip->vendor.timeout_adjusted) {
+       if (!chip->timeout_adjusted) {
                /* Don't overwrite default if value is 0 */
                if (new_timeout[0] != 0 && new_timeout[0] < 1000) {
                        int i;
@@ -572,13 +561,13 @@ int tpm_get_timeouts(struct tpm_chip *chip)
                        /* timeouts in msec rather usec */
                        for (i = 0; i != ARRAY_SIZE(new_timeout); i++)
                                new_timeout[i] *= 1000;
-                       chip->vendor.timeout_adjusted = true;
+                       chip->timeout_adjusted = true;
                }
        }
 
        /* Report adjusted timeouts */
-       if (chip->vendor.timeout_adjusted) {
-               dev_info(chip->pdev,
+       if (chip->timeout_adjusted) {
+               dev_info(&chip->dev,
                         HW_ERR "Adjusting reported timeouts: A %lu->%luus B %lu->%luus C %lu->%luus D %lu->%luus\n",
                         old_timeout[0], new_timeout[0],
                         old_timeout[1], new_timeout[1],
@@ -586,10 +575,10 @@ int tpm_get_timeouts(struct tpm_chip *chip)
                         old_timeout[3], new_timeout[3]);
        }
 
-       chip->vendor.timeout_a = usecs_to_jiffies(new_timeout[0]);
-       chip->vendor.timeout_b = usecs_to_jiffies(new_timeout[1]);
-       chip->vendor.timeout_c = usecs_to_jiffies(new_timeout[2]);
-       chip->vendor.timeout_d = usecs_to_jiffies(new_timeout[3]);
+       chip->timeout_a = usecs_to_jiffies(new_timeout[0]);
+       chip->timeout_b = usecs_to_jiffies(new_timeout[1]);
+       chip->timeout_c = usecs_to_jiffies(new_timeout[2]);
+       chip->timeout_d = usecs_to_jiffies(new_timeout[3]);
 
 duration:
        tpm_cmd.header.in = tpm_getcap_header;
@@ -597,7 +586,7 @@ duration:
        tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
        tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
 
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
                              "attempting to determine the durations");
        if (rc)
                return rc;
@@ -608,11 +597,11 @@ duration:
                return -EINVAL;
 
        duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
-       chip->vendor.duration[TPM_SHORT] =
+       chip->duration[TPM_SHORT] =
            usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
-       chip->vendor.duration[TPM_MEDIUM] =
+       chip->duration[TPM_MEDIUM] =
            usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_medium));
-       chip->vendor.duration[TPM_LONG] =
+       chip->duration[TPM_LONG] =
            usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_long));
 
        /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
@@ -620,12 +609,12 @@ duration:
         * fix up the resulting too-small TPM_SHORT value to make things work.
         * We also scale the TPM_MEDIUM and -_LONG values by 1000.
         */
-       if (chip->vendor.duration[TPM_SHORT] < (HZ / 100)) {
-               chip->vendor.duration[TPM_SHORT] = HZ;
-               chip->vendor.duration[TPM_MEDIUM] *= 1000;
-               chip->vendor.duration[TPM_LONG] *= 1000;
-               chip->vendor.duration_adjusted = true;
-               dev_info(chip->pdev, "Adjusting TPM timeout parameters.");
+       if (chip->duration[TPM_SHORT] < (HZ / 100)) {
+               chip->duration[TPM_SHORT] = HZ;
+               chip->duration[TPM_MEDIUM] *= 1000;
+               chip->duration[TPM_LONG] *= 1000;
+               chip->duration_adjusted = true;
+               dev_info(&chip->dev, "Adjusting TPM timeout parameters.");
        }
        return 0;
 }
@@ -653,7 +642,7 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
        struct tpm_cmd_t cmd;
 
        cmd.header.in = continue_selftest_header;
-       rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0,
                              "continue selftest");
        return rc;
 }
@@ -673,7 +662,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 
        cmd.header.in = pcrread_header;
        cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
-       rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 0,
                              "attempting to read a pcr value");
 
        if (rc == 0)
@@ -700,7 +689,7 @@ int tpm_is_tpm2(u32 chip_num)
 
        rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0;
 
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
 
        return rc;
 }
@@ -729,7 +718,7 @@ int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
                rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
        else
                rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_pcr_read);
@@ -764,17 +753,17 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                rc = tpm2_pcr_extend(chip, pcr_idx, hash);
-               tpm_chip_put(chip);
+               tpm_put_ops(chip);
                return rc;
        }
 
        cmd.header.in = pcrextend_header;
        cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
        memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
-       rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
                              "attempting extend a PCR value");
 
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_pcr_extend);
@@ -793,7 +782,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
        unsigned int loops;
        unsigned int delay_msec = 100;
        unsigned long duration;
-       struct tpm_cmd_t cmd;
+       u8 dummy[TPM_DIGEST_SIZE];
 
        duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);
 
@@ -808,14 +797,15 @@ int tpm_do_selftest(struct tpm_chip *chip)
 
        do {
                /* Attempt to read a PCR value */
-               cmd.header.in = pcrread_header;
-               cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0);
-               rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE);
+               rc = tpm_pcr_read_dev(chip, 0, dummy);
+
                /* Some buggy TPMs will not respond to tpm_tis_ready() for
                 * around 300ms while the self test is ongoing, keep trying
                 * until the self test duration expires. */
                if (rc == -ETIME) {
-                       dev_info(chip->pdev, HW_ERR "TPM command timed out during continue self test");
+                       dev_info(
+                           &chip->dev, HW_ERR
+                           "TPM command timed out during continue self test");
                        msleep(delay_msec);
                        continue;
                }
@@ -823,9 +813,8 @@ int tpm_do_selftest(struct tpm_chip *chip)
                if (rc < TPM_HEADER_SIZE)
                        return -EFAULT;
 
-               rc = be32_to_cpu(cmd.header.out.return_code);
                if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
-                       dev_info(chip->pdev,
+                       dev_info(&chip->dev,
                                 "TPM is disabled/deactivated (0x%X)\n", rc);
                        /* TPM is disabled and/or deactivated; driver can
                         * proceed and TPM does handle commands for
@@ -842,6 +831,33 @@ int tpm_do_selftest(struct tpm_chip *chip)
 }
 EXPORT_SYMBOL_GPL(tpm_do_selftest);
 
+/**
+ * tpm1_auto_startup - Perform the standard automatic TPM initialization
+ *                     sequence
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error.
+ */
+int tpm1_auto_startup(struct tpm_chip *chip)
+{
+       int rc;
+
+       rc = tpm_get_timeouts(chip);
+       if (rc)
+               goto out;
+       rc = tpm_do_selftest(chip);
+       if (rc) {
+               dev_err(&chip->dev, "TPM self test failed\n");
+               goto out;
+       }
+
+       return rc;
+out:
+       if (rc > 0)
+               rc = -ENODEV;
+       return rc;
+}
+
 int tpm_send(u32 chip_num, void *cmd, size_t buflen)
 {
        struct tpm_chip *chip;
@@ -851,9 +867,9 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
        if (chip == NULL)
                return -ENODEV;
 
-       rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
+       rc = tpm_transmit_cmd(chip, cmd, buflen, 0, "attempting tpm_cmd");
 
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_send);
@@ -888,7 +904,7 @@ int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
 
        stop = jiffies + timeout;
 
-       if (chip->vendor.irq) {
+       if (chip->flags & TPM_CHIP_FLAG_IRQ) {
 again:
                timeout = stop - jiffies;
                if ((long)timeout <= 0)
@@ -953,14 +969,15 @@ int tpm_pm_suspend(struct device *dev)
                cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
                memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
                       TPM_DIGEST_SIZE);
-               rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
+               rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
                                      "extending dummy pcr before suspend");
        }
 
        /* now do the actual savestate */
        for (try = 0; try < TPM_RETRY; try++) {
                cmd.header.in = savestate_header;
-               rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
+               rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0,
+                                     NULL);
 
                /*
                 * If the TPM indicates that it is too busy to respond to
@@ -978,10 +995,10 @@ int tpm_pm_suspend(struct device *dev)
        }
 
        if (rc)
-               dev_err(chip->pdev,
+               dev_err(&chip->dev,
                        "Error (%d) sending savestate before suspend\n", rc);
        else if (try > 0)
-               dev_warn(chip->pdev, "TPM savestate took %dms\n",
+               dev_warn(&chip->dev, "TPM savestate took %dms\n",
                         try * TPM_TIMEOUT_RETRY);
 
        return rc;
@@ -1035,7 +1052,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                err = tpm2_get_random(chip, out, max);
-               tpm_chip_put(chip);
+               tpm_put_ops(chip);
                return err;
        }
 
@@ -1044,8 +1061,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
                tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
 
                err = tpm_transmit_cmd(chip, &tpm_cmd,
-                                  TPM_GETRANDOM_RESULT_SIZE + num_bytes,
-                                  "attempting get random");
+                                      TPM_GETRANDOM_RESULT_SIZE + num_bytes,
+                                      0, "attempting get random");
                if (err)
                        break;
 
@@ -1057,7 +1074,7 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
                num_bytes -= recd;
        } while (retries-- && total < max);
 
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
        return total ? total : -EIO;
 }
 EXPORT_SYMBOL_GPL(tpm_get_random);
@@ -1083,7 +1100,7 @@ int tpm_seal_trusted(u32 chip_num, struct trusted_key_payload *payload,
 
        rc = tpm2_seal_trusted(chip, payload, options);
 
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_seal_trusted);
@@ -1109,7 +1126,8 @@ int tpm_unseal_trusted(u32 chip_num, struct trusted_key_payload *payload,
 
        rc = tpm2_unseal_trusted(chip, payload, options);
 
-       tpm_chip_put(chip);
+       tpm_put_ops(chip);
+
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_unseal_trusted);
@@ -1136,6 +1154,7 @@ static int __init tpm_init(void)
 
 static void __exit tpm_exit(void)
 {
+       idr_destroy(&dev_nums_idr);
        class_destroy(tpm_class);
        unregister_chrdev_region(tpm_devt, TPM_NUM_DEVICES);
 }