Some TPMs fail to grant locality when requested immediately after being relinquished. In this case, the TPM_ACCESS_REQUEST_USE bit of the TPM_ACCESS register is cleared immediately without setting TPM_ACCESS_ACTIVE_LOCALITY.
This issue can be seen at boot since tpm_chip_start, called right after locality is relinquished, will fail. This causes the probe to fail: tpm_tis MSFT0101:00: probe with driver tpm_tis failed with error -1 This occurs on some older Dell Latitudes. For the Nuvoton TPM used in these machines, add a delay after locality is relinquished. Signed-off-by: Jim Broadus <[email protected]> --- drivers/char/tpm/tpm_tis_core.c | 6 ++++++ drivers/char/tpm/tpm_tis_core.h | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index d0b87f5daa3e..e0ee98e93ede 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -171,6 +171,9 @@ static int __tpm_tis_relinquish_locality(struct tpm_tis_data *priv, int l) { tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); + if (test_bit(TPM_TIS_SETTLE_AFTER_RELINQUISH, &priv->flags)) + tpm_msleep(TPM_TIMEOUT); + return 0; } @@ -1166,6 +1169,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, if (vendor_id == TPM_VID_IFX) set_bit(TPM_TIS_STATUS_VALID_RETRY, &priv->flags); + if (vendor_id == TPM_VID_WINBOND && device_id == 0x00FE) + set_bit(TPM_TIS_SETTLE_AFTER_RELINQUISH, &priv->flags); + if (is_bsw()) { priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, ILB_REMAP_SIZE); diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index f2c77844062a..aa6d78898ef3 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -90,6 +90,7 @@ enum tpm_tis_flags { TPM_TIS_DEFAULT_CANCELLATION = 2, TPM_TIS_IRQ_TESTED = 3, TPM_TIS_STATUS_VALID_RETRY = 4, + TPM_TIS_SETTLE_AFTER_RELINQUISH = 5, }; struct tpm_tis_data { -- 2.54.0

