summaryrefslogtreecommitdiff
path: root/src/drivers/i2c/tpm/tpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/i2c/tpm/tpm.c')
-rw-r--r--src/drivers/i2c/tpm/tpm.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/drivers/i2c/tpm/tpm.c b/src/drivers/i2c/tpm/tpm.c
index f0f5ca8d6c..f75bcd7269 100644
--- a/src/drivers/i2c/tpm/tpm.c
+++ b/src/drivers/i2c/tpm/tpm.c
@@ -539,7 +539,7 @@ static int cr50_wait_burst_status(struct tpm_chip *chip, uint8_t mask,
uint8_t buf[4];
struct stopwatch sw;
- stopwatch_init_usecs_expire(&sw, 10 * SLEEP_DURATION_SAFE);
+ stopwatch_init_msecs_expire(&sw, 2000);
while (!stopwatch_expired(&sw)) {
if (iic_tpm_read(TPM_STS(chip->vendor.locality),
@@ -628,7 +628,6 @@ static int cr50_tis_i2c_recv(struct tpm_chip *chip, uint8_t *buf,
ret = current;
out:
- cr50_tis_i2c_ready(chip);
return ret;
}
@@ -637,17 +636,23 @@ static int cr50_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
int status;
size_t burstcnt, limit, sent = 0;
uint8_t tpm_go[4] = { TPM_STS_GO };
+ struct stopwatch sw;
if (len > TPM_BUFSIZE)
return -1;
+ stopwatch_init_msecs_expire(&sw, 2000);
+
/* Wait until TPM is ready for a command */
- status = cr50_tis_i2c_status(chip);
- if (!(status & TPM_STS_COMMAND_READY)) {
+ while (!(cr50_tis_i2c_status(chip) & TPM_STS_COMMAND_READY)) {
+ if (stopwatch_expired(&sw)) {
+ printk(BIOS_ERR, "%s: Command ready timeout\n",
+ __func__);
+ return -1;
+ }
+
cr50_tis_i2c_ready(chip);
- if (cr50_wait_burst_status(chip, TPM_STS_COMMAND_READY,
- &burstcnt, &status) < 0)
- goto out;
+ udelay(SLEEP_DURATION_SAFE);
}
while (len > 0) {
@@ -690,7 +695,9 @@ static int cr50_tis_i2c_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
return sent;
out:
- cr50_tis_i2c_ready(chip);
+ /* Abort current transaction if still pending */
+ if (cr50_tis_i2c_status(chip) & TPM_STS_COMMAND_READY)
+ cr50_tis_i2c_ready(chip);
return -1;
}
@@ -721,6 +728,7 @@ int tpm_vendor_probe(unsigned bus, uint32_t addr)
sw_run_duration = stopwatch_duration_msecs(&sw);
break;
}
+ udelay(SLEEP_DURATION_SAFE);
} while (!stopwatch_expired(&sw));
printk(BIOS_INFO,
@@ -747,6 +755,7 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned bus, uint32_t dev_addr)
return -1;
}
+ tpm_dev->chip_type = UNKNOWN;
tpm_dev->bus = bus;
tpm_dev->addr = dev_addr;