tpm: rework tpm_get_timeouts()
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Wed, 25 Nov 2015 21:05:32 +0000 (14:05 -0700)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Sun, 20 Dec 2015 13:23:46 +0000 (15:23 +0200)
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 <jgunthorpe@obsidianresearch.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Martin Wilck <Martin.Wilck@ts.fujitsu.com>
Tested-by: Scot Doyle <lkml14@scotdoyle.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Acked-by: Peter Huewe <peterhuewe@gmx.de>
drivers/char/tpm/tpm-interface.c
drivers/char/tpm/tpm_crb.c
drivers/char/tpm/tpm_tis.c

index afdc836..e2fa89c 100644 (file)
@@ -503,6 +503,21 @@ int tpm_get_timeouts(struct tpm_chip *chip)
        struct duration_t *duration_cap;
        ssize_t rc;
 
        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);
        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);
index 4bb9727..8342cf5 100644 (file)
@@ -284,17 +284,9 @@ static int crb_acpi_add(struct acpi_device *device)
 
        chip->vendor.priv = priv;
 
 
        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;
 
 
        chip->acpi_dev_handle = device->handle;
 
index 513f30e..56a295d 100644 (file)
@@ -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");
 
        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);
        /* 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));
 
                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");
                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 {
                        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;
                if (tpm_do_selftest(chip)) {
                        dev_err(dev, "TPM self test failed\n");
                        rc = -ENODEV;