diff options
author | Jarkko Sakkinen <jarkko@kernel.org> | 2021-02-20 00:55:59 +0200 |
---|---|---|
committer | Jarkko Sakkinen <jarkko@kernel.org> | 2021-02-24 18:53:22 +0200 |
commit | a5665ec2affdba21bff3b0d4d3aed83b3951e8ff (patch) | |
tree | 587214574562dd8c303345d756891792cee3ce1a /drivers/char | |
parent | c03c21ba6f4e95e406a1a7b4c34ef334b977c194 (diff) |
tpm, tpm_tis: Decorate tpm_get_timeouts() with request_locality()
This is shown with Samsung Chromebook Pro (Caroline) with TPM 1.2
(SLB 9670):
[ 4.324298] TPM returned invalid status
[ 4.324806] WARNING: CPU: 2 PID: 1 at drivers/char/tpm/tpm_tis_core.c:275 tpm_tis_status+0x86/0x8f
Background
==========
TCG PC Client Platform TPM Profile (PTP) Specification, paragraph 6.1 FIFO
Interface Locality Usage per Register, Table 39 Register Behavior Based on
Locality Setting for FIFO - a read attempt to TPM_STS_x Registers returns
0xFF in case of lack of locality.
The fix
=======
Decorate tpm_get_timeouts() with request_locality() and release_locality().
Fixes: a3fbfae82b4c ("tpm: take TPM chip power gating out of tpm_transmit()")
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: Laurent Bigonville <bigon@debian.org>
Cc: stable@vger.kernel.org
Reported-by: Lukasz Majczak <lma@semihalf.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tpm/tpm_tis_core.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 431919d5f48a..30843954aa36 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -1019,11 +1019,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, init_waitqueue_head(&priv->read_queue); init_waitqueue_head(&priv->int_queue); if (irq != -1) { - /* Before doing irq testing issue a command to the TPM in polling mode + /* + * Before doing irq testing issue a command to the TPM in polling mode * to make sure it works. May as well use that command to set the * proper timeouts for the driver. */ - if (tpm_get_timeouts(chip)) { + + rc = request_locality(chip, 0); + if (rc < 0) + goto out_err; + + rc = tpm_get_timeouts(chip); + + release_locality(chip, 0); + + if (rc) { dev_err(dev, "Could not get TPM timeouts and durations\n"); rc = -ENODEV; goto out_err; |