Commit 1398aa80 authored by Jarkko Sakkinen's avatar Jarkko Sakkinen

tpm_tis: Use tpm_chip_{start,stop} decoration inside tpm_tis_resume

Before sending a TPM command, CLKRUN protocol must be disabled. This is not
done in the case of tpm1_do_selftest() call site inside tpm_tis_resume().

Address this by decorating the calls with tpm_chip_{start,stop}, which
should be always used to arm and disarm the TPM chip for transmission.

Finally, move the call to the main TPM driver callback as the last step
because it should arm the chip by itself, if it needs that type of
functionality.

Cc: stable@vger.kernel.org
Reported-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Closes: https://lore.kernel.org/linux-integrity/CS68AWILHXS4.3M36M1EKZLUMS@suppilovahvero/
Fixes: a3fbfae8 ("tpm: take TPM chip power gating out of tpm_transmit()")
Reviewed-by: default avatarJerry Snitselaar <jsnitsel@redhat.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko@kernel.org>
parent f1fcbaa1
......@@ -1209,25 +1209,20 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip)
u32 intmask;
int rc;
if (chip->ops->clk_enable != NULL)
chip->ops->clk_enable(chip, true);
/* reenable interrupts that device may have lost or
* BIOS/firmware may have disabled
/*
* Re-enable interrupts that device may have lost or BIOS/firmware may
* have disabled.
*/
rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq);
if (rc < 0)
goto out;
if (rc < 0) {
dev_err(&chip->dev, "Setting IRQ failed.\n");
return;
}
intmask = priv->int_mask | TPM_GLOBAL_INT_ENABLE;
tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
out:
if (chip->ops->clk_enable != NULL)
chip->ops->clk_enable(chip, false);
return;
rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
if (rc < 0)
dev_err(&chip->dev, "Enabling interrupts failed.\n");
}
int tpm_tis_resume(struct device *dev)
......@@ -1235,27 +1230,27 @@ int tpm_tis_resume(struct device *dev)
struct tpm_chip *chip = dev_get_drvdata(dev);
int ret;
ret = tpm_tis_request_locality(chip, 0);
if (ret < 0)
ret = tpm_chip_start(chip);
if (ret)
return ret;
if (chip->flags & TPM_CHIP_FLAG_IRQ)
tpm_tis_reenable_interrupts(chip);
ret = tpm_pm_resume(dev);
if (ret)
goto out;
/*
* TPM 1.2 requires self-test on resume. This function actually returns
* an error code but for unknown reason it isn't handled.
*/
if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
tpm1_do_selftest(chip);
out:
tpm_tis_relinquish_locality(chip, 0);
return ret;
tpm_chip_stop(chip);
ret = tpm_pm_resume(dev);
if (ret)
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(tpm_tis_resume);
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment