From 25112048cd59930e23775cafb88e18cfb484892c Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Wed, 25 Nov 2015 14:05:32 -0700 Subject: tpm: rework tpm_get_timeouts() IRQ probing needs to know that the TPM is working before trying to probe, so move tpm_get_timeouts() to the top of the tpm_tis_init(). This has the advantage of also getting the correct timeouts loaded before doing IRQ probing. All the timeout handling code is moved to tpm_get_timeouts() in order to remove duplicate code in tpm_tis and tpm_crb. [jarkko.sakkinen@linux.intel.com: squashed two patches together and improved the commit message.] Signed-off-by: Jason Gunthorpe Reviewed-by: Jarkko Sakkinen Tested-by: Jarkko Sakkinen Tested-by: Martin Wilck Tested-by: Scot Doyle Signed-off-by: Jarkko Sakkinen Acked-by: Peter Huewe --- drivers/char/tpm/tpm-interface.c | 15 +++++++++++++++ drivers/char/tpm/tpm_crb.c | 14 +++----------- drivers/char/tpm/tpm_tis.c | 33 ++++++++++++++++----------------- 3 files changed, 34 insertions(+), 28 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index afdc83602e9f..e2fa89c88304 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -503,6 +503,21 @@ int tpm_get_timeouts(struct tpm_chip *chip) struct duration_t *duration_cap; ssize_t rc; + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + /* Fixed timeouts for TPM2 */ + chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); + chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); + chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); + chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); + chip->vendor.duration[TPM_SHORT] = + msecs_to_jiffies(TPM2_DURATION_SHORT); + chip->vendor.duration[TPM_MEDIUM] = + msecs_to_jiffies(TPM2_DURATION_MEDIUM); + chip->vendor.duration[TPM_LONG] = + msecs_to_jiffies(TPM2_DURATION_LONG); + return 0; + } + tpm_cmd.header.in = tpm_getcap_header; tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP; tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4); diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 4bb9727c1047..8342cf51ffdc 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -284,17 +284,9 @@ static int crb_acpi_add(struct acpi_device *device) chip->vendor.priv = priv; - /* Default timeouts and durations */ - chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); - chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); - chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); - chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); - chip->vendor.duration[TPM_SHORT] = - msecs_to_jiffies(TPM2_DURATION_SHORT); - chip->vendor.duration[TPM_MEDIUM] = - msecs_to_jiffies(TPM2_DURATION_MEDIUM); - chip->vendor.duration[TPM_LONG] = - msecs_to_jiffies(TPM2_DURATION_LONG); + rc = tpm_get_timeouts(chip); + if (rc) + return rc; chip->acpi_dev_handle = device->handle; diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 513f30efd9d3..56a295d328c7 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -740,6 +740,16 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, if (intfcaps & TPM_INTF_DATA_AVAIL_INT) dev_dbg(dev, "\tData Avail Int Support\n"); + /* Very early on 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)) { + dev_err(dev, "Could not get TPM timeouts and durations\n"); + rc = -ENODEV; + goto out_err; + } + /* INTERRUPT Setup */ init_waitqueue_head(&chip->vendor.read_queue); init_waitqueue_head(&chip->vendor.int_queue); @@ -837,18 +847,13 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, iowrite8(irq_r, chip->vendor.iobase + TPM_INT_VECTOR(chip->vendor.locality)); - if (chip->flags & TPM_CHIP_FLAG_TPM2) { - chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); - chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); - chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); - chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); - chip->vendor.duration[TPM_SHORT] = - msecs_to_jiffies(TPM2_DURATION_SHORT); - chip->vendor.duration[TPM_MEDIUM] = - msecs_to_jiffies(TPM2_DURATION_MEDIUM); - chip->vendor.duration[TPM_LONG] = - msecs_to_jiffies(TPM2_DURATION_LONG); + if (tpm_get_timeouts(chip)) { + dev_err(dev, "Could not get TPM timeouts and durations\n"); + rc = -ENODEV; + goto out_err; + } + if (chip->flags & TPM_CHIP_FLAG_TPM2) { rc = tpm2_do_selftest(chip); if (rc == TPM2_RC_INITIALIZE) { dev_warn(dev, "Firmware has not started TPM\n"); @@ -864,12 +869,6 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, goto out_err; } } else { - if (tpm_get_timeouts(chip)) { - dev_err(dev, "Could not get TPM timeouts and durations\n"); - rc = -ENODEV; - goto out_err; - } - if (tpm_do_selftest(chip)) { dev_err(dev, "TPM self test failed\n"); rc = -ENODEV; -- cgit v1.2.3