diff options
| author | Christophe Ricard <christophe.ricard@gmail.com> | 2015-03-23 17:29:56 -0400 |
|---|---|---|
| committer | Peter Huewe <peterhuewe@gmx.de> | 2015-03-26 21:50:34 -0400 |
| commit | 7216ebc51bdd62517be6878dd37555ff428a80c9 (patch) | |
| tree | ecb34d5c217374747ec38c2ccd6b42bae09e4bbb | |
| parent | 6b37729bd184fdd44f144c6cc4951b06b55bcf4b (diff) | |
tpm/st33zp24: Add proper wait for ordinal duration in case of irq mode
In case the driver is configured to use irq, we are not waiting the answer
for a duration period to see the DATA_AVAIL status bit to raise but at
maximum timeout_c. This may result in critical failure as we will
not wait long enough for the command completion.
Reviewed-by: Jason Gunthorpe <jason.gunthorpe@obsidianresearch.com>
Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
Fixes: bf38b8710892 ("tpm/tpm_i2c_stm_st33: Split tpm_i2c_tpm_st33 in 2
layers (core + phy)")
Reviewed-by: Peter Huewe <peterhuewe@gmx.de>
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
| -rw-r--r-- | drivers/char/tpm/st33zp24/st33zp24.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 03f254384585..8d626784cd8d 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c | |||
| @@ -393,7 +393,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id) | |||
| 393 | static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, | 393 | static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, |
| 394 | size_t len) | 394 | size_t len) |
| 395 | { | 395 | { |
| 396 | u32 status, i, size; | 396 | u32 status, i, size, ordinal; |
| 397 | int burstcnt = 0; | 397 | int burstcnt = 0; |
| 398 | int ret; | 398 | int ret; |
| 399 | u8 data; | 399 | u8 data; |
| @@ -456,6 +456,16 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, | |||
| 456 | if (ret < 0) | 456 | if (ret < 0) |
| 457 | goto out_err; | 457 | goto out_err; |
| 458 | 458 | ||
| 459 | if (chip->vendor.irq) { | ||
| 460 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); | ||
| 461 | |||
| 462 | ret = wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
| 463 | tpm_calc_ordinal_duration(chip, ordinal), | ||
| 464 | &chip->vendor.read_queue, false); | ||
| 465 | if (ret < 0) | ||
| 466 | goto out_err; | ||
| 467 | } | ||
| 468 | |||
| 459 | return len; | 469 | return len; |
| 460 | out_err: | 470 | out_err: |
| 461 | st33zp24_cancel(chip); | 471 | st33zp24_cancel(chip); |
