From fc841edc9b4036bed36126dbdc7fdd41cee185c8 Mon Sep 17 00:00:00 2001 From: Jarkko Sakkinen Date: Fri, 13 Nov 2026 20:18:42 +0200 Subject: [PATCH] tpm: Cache TPM2 start method Both tpm_tis and tpm_crb have duplicate code for retrieving the start method from TPM2 ACPI table. Eagerly cache the start method already at chip creation. The cached chip->start_method can then be used by the leaf drivers; or ignored depending on the requirements. Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm-chip.c | 36 +++++++++++++++++++++++++++++------- include/linux/tpm.h | 1 + 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 0be5dbfaa72e..540dd366effc 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -256,18 +256,24 @@ int tpm_class_shutdown(struct device *dev) } /** - * tpm_chip_alloc() - allocate a new struct tpm_chip instance - * @pdev: device to which the chip is associated - * At this point pdev mst be initialized, but does not have to - * be registered - * @ops: struct tpm_class_ops instance + * tpm_chip_alloc() - Allocate a new struct tpm_chip instance + * @pdev: device to which the chip is associated At this point pdev mst be + * initialized, but does not have to be registered + * @ops: struct tpm_class_ops for the chip. + * + * Allocates a new struct tpm_chip instance, and assigns a free device number + * for it. Must be paired with put_device(&chip->dev). * - * Allocates a new struct tpm_chip instance and assigns a free - * device number for it. Must be paired with put_device(&chip->dev). + * When ACPI is enabled, additionally tries to eagerly cache the start method + * from TPM2 ACPI table for the devices that need know it. */ struct tpm_chip *tpm_chip_alloc(struct device *pdev, const struct tpm_class_ops *ops) { +#ifdef CONFIG_ACPI + struct acpi_table_tpm2 *tbl; + acpi_status status; +#endif struct tpm_chip *chip; int rc; @@ -275,6 +281,22 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, if (chip == NULL) return ERR_PTR(-ENOMEM); +#ifdef CONFIG_ACPI + chip->start_method = ACPI_TPM2_NOT_ALLOWED; + if (!acpi_disabled) { + status = acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl); + if (!ACPI_FAILURE(status) || tbl->header.length >= sizeof(*tbl)) { + chip->start_method = tbl->start_method; + dev_info(pdev, "TPM2 ACPI table is available"); + } else { + dev_info(pdev, "TPM2 ACPI table is not available"); + } + + if (!ACPI_FAILURE(status)) + acpi_put_table((struct acpi_table_header *)tbl); + } +#endif + mutex_init(&chip->tpm_mutex); init_rwsem(&chip->ops_sem); diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 0db277af45c3..f6cc91615469 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -149,6 +149,7 @@ struct tpm_chip { struct tpm_bank_info allocated_banks[TPM2_MAX_PCR_BANKS]; #ifdef CONFIG_ACPI acpi_handle acpi_dev_handle; + u32 start_method; char ppi_version[TPM_PPI_VERSION_LEN + 1]; #endif /* CONFIG_ACPI */ -- 2.47.3