tpm/st33zp24: Add proper wait for ordinal duration in case of irq mode
authorChristophe Ricard <christophe.ricard@gmail.com>
Mon, 23 Mar 2015 21:29:56 +0000 (22:29 +0100)
committerPeter Huewe <peterhuewe@gmx.de>
Fri, 27 Mar 2015 01:50:34 +0000 (02:50 +0100)
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>
drivers/char/tpm/st33zp24/st33zp24.c

index 03f25438458521c8b9140f72c5552d3232cb8270..8d626784cd8dd8bec4f61ceb568fe06cac2bb995 100644 (file)
@@ -393,7 +393,7 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
 static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
                         size_t len)
 {
-       u32 status, i, size;
+       u32 status, i, size, ordinal;
        int burstcnt = 0;
        int ret;
        u8 data;
@@ -456,6 +456,16 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
        if (ret < 0)
                goto out_err;
 
+       if (chip->vendor.irq) {
+               ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
+
+               ret = wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+                               tpm_calc_ordinal_duration(chip, ordinal),
+                               &chip->vendor.read_queue, false);
+               if (ret < 0)
+                       goto out_err;
+       }
+
        return len;
 out_err:
        st33zp24_cancel(chip);