aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm2-cmd.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2016-07-12 11:41:49 -0600
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2016-07-19 17:43:38 +0300
commitcae8b441fc20812d7260dc3b45e05ee98fcfff1b (patch)
tree25c43fb7bd96f438d00cdf6b6ca233a4e4995257 /drivers/char/tpm/tpm2-cmd.c
parenttpm: use devm_add_action_or_reset (diff)
downloadlinux-dev-cae8b441fc20812d7260dc3b45e05ee98fcfff1b.tar.xz
linux-dev-cae8b441fc20812d7260dc3b45e05ee98fcfff1b.zip
tpm: Factor out common startup code
The TCG standard startup sequence (get timeouts, tpm startup, etc) for TPM and TPM2 chips is being open coded in many drivers, move it into the core code. tpm_tis and tpm_crb are used as the basis for the core code implementation and the easy drivers are converted. In the process several small drivers bugs relating to error handling this flow are fixed. For now the flag TPM_OPS_AUTO_STARTUP is optional to allow a staged driver roll out, but ultimately all drivers should use this flow and the flag removed. Some drivers still do not implement the startup sequence at all and will need to be tested with it enabled. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Tested-by: Andrew Zamansky <andrew.zamansky@nuvoton.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Diffstat (limited to 'drivers/char/tpm/tpm2-cmd.c')
-rw-r--r--drivers/char/tpm/tpm2-cmd.c46
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index a88b31e7fe72..08c7e23ed535 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -728,7 +728,7 @@ static const struct tpm_input_header tpm2_startup_header = {
* returned it remarks a POSIX error code. If a positive number is returned
* it remarks a TPM error.
*/
-int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
+static int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
{
struct tpm2_cmd cmd;
@@ -738,7 +738,6 @@ int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
return tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
"attempting to start the TPM");
}
-EXPORT_SYMBOL_GPL(tpm2_startup);
#define TPM2_SHUTDOWN_IN_SIZE \
(sizeof(struct tpm_input_header) + \
@@ -854,7 +853,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
* returned it remarks a POSIX error code. If a positive number is returned
* it remarks a TPM error.
*/
-int tpm2_do_selftest(struct tpm_chip *chip)
+static int tpm2_do_selftest(struct tpm_chip *chip)
{
int rc;
unsigned int loops;
@@ -894,7 +893,6 @@ int tpm2_do_selftest(struct tpm_chip *chip)
return rc;
}
-EXPORT_SYMBOL_GPL(tpm2_do_selftest);
/**
* tpm2_gen_interrupt() - generate an interrupt
@@ -942,3 +940,43 @@ int tpm2_probe(struct tpm_chip *chip)
return 0;
}
EXPORT_SYMBOL_GPL(tpm2_probe);
+
+/**
+ * tpm2_auto_startup - Perform the standard automatic TPM initialization
+ * sequence
+ * @chip: TPM chip to use
+ *
+ * Returns 0 on success, < 0 in case of fatal error.
+ */
+int tpm2_auto_startup(struct tpm_chip *chip)
+{
+ int rc;
+
+ rc = tpm_get_timeouts(chip);
+ if (rc)
+ goto out;
+
+ rc = tpm2_do_selftest(chip);
+ if (rc != TPM2_RC_INITIALIZE) {
+ dev_err(&chip->dev, "TPM self test failed\n");
+ goto out;
+ }
+
+ if (rc == TPM2_RC_INITIALIZE) {
+ rc = tpm2_startup(chip, TPM2_SU_CLEAR);
+ if (rc)
+ goto out;
+
+ rc = tpm2_do_selftest(chip);
+ if (rc) {
+ dev_err(&chip->dev, "TPM self test failed\n");
+ goto out;
+ }
+ }
+
+ return rc;
+out:
+ if (rc > 0)
+ rc = -ENODEV;
+ return rc;
+}