]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - drivers/char/tpm/tpm_tis_core.c
tpm_tis: Fix an error handling path in 'tpm_tis_core_init()'
[mirror_ubuntu-jammy-kernel.git] / drivers / char / tpm / tpm_tis_core.c
index 69579efb247b3b7508df00d5796cb9d429db3889..36d1ad8f479d77ba5fa824f9720199b0396d03d4 100644 (file)
@@ -48,6 +48,7 @@ static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask,
                unsigned long timeout, wait_queue_head_t *queue,
                bool check_cancel)
 {
+       struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
        unsigned long stop;
        long rc;
        u8 status;
@@ -80,8 +81,8 @@ again:
                }
        } else {
                do {
-                       usleep_range(TPM_TIMEOUT_USECS_MIN,
-                                    TPM_TIMEOUT_USECS_MAX);
+                       usleep_range(priv->timeout_min,
+                                    priv->timeout_max);
                        status = chip->ops->status(chip);
                        if ((status & mask) == mask)
                                return 0;
@@ -945,7 +946,22 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
        chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX);
        chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX);
        chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX);
+       priv->timeout_min = TPM_TIMEOUT_USECS_MIN;
+       priv->timeout_max = TPM_TIMEOUT_USECS_MAX;
        priv->phy_ops = phy_ops;
+
+       rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
+       if (rc < 0)
+               return rc;
+
+       priv->manufacturer_id = vendor;
+
+       if (priv->manufacturer_id == TPM_VID_ATML &&
+               !(chip->flags & TPM_CHIP_FLAG_TPM2)) {
+               priv->timeout_min = TIS_TIMEOUT_MIN_ATML;
+               priv->timeout_max = TIS_TIMEOUT_MAX_ATML;
+       }
+
        dev_set_drvdata(&chip->dev, priv);
 
        if (is_bsw()) {
@@ -978,7 +994,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
        intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
                   TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
        intmask &= ~TPM_GLOBAL_INT_ENABLE;
+
+       rc = request_locality(chip, 0);
+       if (rc < 0) {
+               rc = -ENODEV;
+               goto out_err;
+       }
+
        tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
+       release_locality(chip, 0);
 
        rc = tpm_chip_start(chip);
        if (rc)
@@ -988,12 +1012,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
        if (rc)
                goto out_err;
 
-       rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor);
-       if (rc < 0)
-               goto out_err;
-
-       priv->manufacturer_id = vendor;
-
        rc = tpm_tis_read8(priv, TPM_RID(0), &rid);
        if (rc < 0)
                goto out_err;