tpm2_i2c_infineon has guards that trigger retrying reading from STS register in case 0xFF is returned. However, the don't cover all cases. If STS continuously return 0xFF over 20 reads within 5-7ms, the following might happen in wait_for_stat():
- wait_for_stat() calls tpm_tis_i2c_status() for the first time;
- tpm_tis_i2c_status reads 0xFF 10 times, gives up and returns 0xFF;
- wait_for_stat() ignores 0xFF, enters retry cycle and sleeps for 5-7ms: usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
- wait_for_stat() calls tpm_tis_i2c_status() again;
- tpm_tis_i2c_status reads 0xFF 10 times, gives up and returns 0xFF;
- wait_for_stat() this time accepts 0xFF as a valid value and returns it.
To fix that, do one or both:
a) In tpm_tis_i2c_status() if the value is still 0xFF after 10 retries, return 0 instead of 0xFF.
b) In wait_for_stat() in the retry loop, each time check if the value is 0xFF, and ignore if so.
Possible example from real life: http://b/33758106#comment131
Comment 1 by apronin@chromium.org
, Jun 26 2018