diff mbox

[tpmdd-devel,v3] tpm/tpm_i2c_stm_st33: Add proper wait for ordinal duration in case of irq mode

Message ID 1427179633-3246-2-git-send-email-christophe-h.ricard@st.com
State Accepted
Headers show

Commit Message

Christophe Ricard March 24, 2015, 6:47 a.m. UTC
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.

This patch is a backport from kernel 4.1 fix.

Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>
---
 drivers/char/tpm/tpm_i2c_stm_st33.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Peter Hüwe March 27, 2015, 1:36 a.m. UTC | #1
Am Dienstag, 24. März 2015, 07:47:13 schrieb Christophe Ricard:
> 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.
> 
> This patch is a backport from kernel 4.1 fix.
> 
> Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>


Cc: <stable@vger.kernel.org>
Fixes: 251a7b08213a ("TPM: STMicroelectronics ST33 I2C KERNEL 3.x")
Reviewed-by: Peter Huewe <peterhuewe@gmx.de>
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
Peter Hüwe March 27, 2015, 2:02 a.m. UTC | #2
Hi Christophe,

Am Dienstag, 24. März 2015, 07:47:13 schrieb Christophe Ricard:
> 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.
> 
> This patch is a backport from kernel 4.1 fix.
> 
> Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com>

I thought about it a bit and decided the following strategy:
For 4.1 I have the fix included in the pull request I just sent out - so spi 
devices are covered with the introduction of the spi code (i.e. 4.1)

For the i2c based devices the issue exists since the introduction of the code 
which was 2012 - so effectively nobody seems to use irqs here :) and thus it's 
not super duper critical that we have to push it into 4.0-rc6/7 (which is 
ultra late) and cause a merge error with the driver-split introduced in 4.1.

--> So once the pull request is merged, I'll post the backported patch 
directly to stable so it will be included in the next stable release for all 
kernel versions that include the i2c driver.

Thanks,
Peter

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
diff mbox

Patch

diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c
index 612845b..5850222 100644
--- a/drivers/char/tpm/tpm_i2c_stm_st33.c
+++ b/drivers/char/tpm/tpm_i2c_stm_st33.c
@@ -496,7 +496,7 @@  static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
 static int tpm_stm_i2c_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;
@@ -559,6 +559,16 @@  static int tpm_stm_i2c_send(struct tpm_chip *chip, unsigned char *buf,
 	data = TPM_STS_GO;
 	I2C_WRITE_DATA(tpm_dev, TPM_STS, &data, 1);
 
+	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:
 	tpm_stm_i2c_cancel(chip);