From: Stefan Berger Date: Wed, 18 Jan 2012 03:07:30 +0000 (-0500) Subject: tpm: fix (ACPI S3) suspend regression X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=be405411f712489f2f780ab085e1069e8fb85f19;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git tpm: fix (ACPI S3) suspend regression This patch fixes an (ACPI S3) suspend regression introduced in commit 68d6e6713fcb ("tpm: Introduce function to poll for result of self test") and occurring with an Infineon TPM and tpm_tis and tpm_infineon drivers active. The suspend problem occurred if the TPM was disabled and/or deactivated and therefore the TPM_PCRRead checking the result of the (asynchronous) self test returned an error code which then caused the tpm_tis driver to become inactive and this then seemed to have negatively influenced the suspend support by the tpm_infineon driver... Besides that the tpm_tis drive may stay active even if the TPM is disabled and/or deactivated. Signed-off-by: Stefan Berger Tested-by: Rafael J. Wysocki Acked-by: Rajiv Andrade Signed-off-by: Linus Torvalds --- diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 6a8771f47a55..32362cf35b8d 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -846,6 +846,15 @@ int tpm_do_selftest(struct tpm_chip *chip) do { rc = __tpm_pcr_read(chip, 0, digest); + if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) { + dev_info(chip->dev, + "TPM is disabled/deactivated (0x%X)\n", rc); + /* TPM is disabled and/or deactivated; driver can + * proceed and TPM does handle commands for + * suspend/resume correctly + */ + return 0; + } if (rc != TPM_WARN_DOING_SELFTEST) return rc; msleep(delay_msec); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 8c1df302fbb6..010547138281 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -39,6 +39,9 @@ enum tpm_addr { }; #define TPM_WARN_DOING_SELFTEST 0x802 +#define TPM_ERR_DEACTIVATED 0x6 +#define TPM_ERR_DISABLED 0x7 + #define TPM_HEADER_SIZE 10 extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, char *);