aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Chiu <chiu@endlessm.com>2018-03-20 03:36:40 -0400
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2018-03-23 04:25:02 -0400
commit0803d7befa15cab5717d667a97a66214d2a4c083 (patch)
treee79cfa54e0f0730467231f49b6f747d217f77427
parent076d356460273e3c702f46fc87471b508fb55e7b (diff)
tpm: self test failure should not cause suspend to fail
The Acer Acer Veriton X4110G has a TPM device detected as: tpm_tis 00:0b: 1.2 TPM (device-id 0xFE, rev-id 71) After the first S3 suspend, the following error appears during resume: tpm tpm0: A TPM error(38) occurred continue selftest Any following S3 suspend attempts will now fail with this error: tpm tpm0: Error (38) sending savestate before suspend PM: Device 00:0b failed to suspend: error 38 Error 38 is TPM_ERR_INVALID_POSTINIT which means the TPM is not in the correct state. This indicates that the platform BIOS is not sending the usual TPM_Startup command during S3 resume. >From this point onwards, all TPM commands will fail. The same issue was previously reported on Foxconn 6150BK8MC and Sony Vaio TX3. The platform behaviour seems broken here, but we should not break suspend/resume because of this. When the unexpected TPM state is encountered, set a flag to skip the affected TPM_SaveState command on later suspends. Cc: stable@vger.kernel.org Signed-off-by: Chris Chiu <chiu@endlessm.com> Signed-off-by: Daniel Drake <drake@endlessm.com> Link: http://lkml.kernel.org/r/CAB4CAwfSCvj1cudi+MWaB5g2Z67d9DwY1o475YOZD64ma23UiQ@mail.gmail.com Link: https://lkml.org/lkml/2011/3/28/192 Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=591031 Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
-rw-r--r--drivers/char/tpm/tpm-interface.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 47aacecdc85c..22288ff70a0b 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -1002,6 +1002,10 @@ int tpm_do_selftest(struct tpm_chip *chip)
1002 loops = jiffies_to_msecs(duration) / delay_msec; 1002 loops = jiffies_to_msecs(duration) / delay_msec;
1003 1003
1004 rc = tpm_continue_selftest(chip); 1004 rc = tpm_continue_selftest(chip);
1005 if (rc == TPM_ERR_INVALID_POSTINIT) {
1006 chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
1007 dev_info(&chip->dev, "TPM not ready (%d)\n", rc);
1008 }
1005 /* This may fail if there was no TPM driver during a suspend/resume 1009 /* This may fail if there was no TPM driver during a suspend/resume
1006 * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST) 1010 * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
1007 */ 1011 */