Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tpm_tis: Consolidate the platform and acpi probe flow

Now that the platform device was merged for OF support we can use the
platform device to match ACPI devices as well and run everything
through tpm_tis_init.

pnp_acpi_device is replaced with ACPI_COMPANION, and ACPI_HANDLE is
pushed further down.

platform_get_resource is used instead of acpi_dev_get_resources.

The itpm global module parameter is no longer changed during itpm
detection, instead the phy specific bit is set directly.

Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jerry Snitselaar <jsnitsel@redhat.com> (with TPM 2.0)
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> (with TPM 1.2)
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>

authored by

Jason Gunthorpe and committed by
Jarkko Sakkinen
4cb586a1 fc0e1322

+54 -113
+54 -113
drivers/char/tpm/tpm_tis.c
··· 80 80 81 81 static inline int is_itpm(struct acpi_device *dev) 82 82 { 83 + if (!dev) 84 + return 0; 83 85 return has_hid(dev, "INTC0102"); 84 86 } 85 87 #else 86 88 static inline int is_itpm(struct acpi_device *dev) 89 + { 90 + return 0; 91 + } 92 + #endif 93 + 94 + #if defined(CONFIG_ACPI) 95 + #define DEVICE_IS_TPM2 1 96 + 97 + static const struct acpi_device_id tpm_acpi_tbl[] = { 98 + {"MSFT0101", DEVICE_IS_TPM2}, 99 + {}, 100 + }; 101 + MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl); 102 + 103 + static int check_acpi_tpm2(struct device *dev) 104 + { 105 + const struct acpi_device_id *aid = acpi_match_device(tpm_acpi_tbl, dev); 106 + struct acpi_table_tpm2 *tbl; 107 + acpi_status st; 108 + 109 + if (!aid || aid->driver_data != DEVICE_IS_TPM2) 110 + return 0; 111 + 112 + /* If the ACPI TPM2 signature is matched then a global ACPI_SIG_TPM2 113 + * table is mandatory 114 + */ 115 + st = 116 + acpi_get_table(ACPI_SIG_TPM2, 1, (struct acpi_table_header **)&tbl); 117 + if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) { 118 + dev_err(dev, FW_BUG "failed to get TPM2 ACPI table\n"); 119 + return -EINVAL; 120 + } 121 + 122 + /* The tpm2_crb driver handles this device */ 123 + if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED) 124 + return -ENODEV; 125 + 126 + return 0; 127 + } 128 + #else 129 + static int check_acpi_tpm2(struct device *dev) 87 130 { 88 131 return 0; 89 132 } ··· 184 141 .write32 = tpm_tcg_write32, 185 142 }; 186 143 187 - static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, 188 - acpi_handle acpi_dev_handle) 144 + static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info) 189 145 { 190 146 struct tpm_tis_tcg_phy *phy; 191 147 int irq = -1; 148 + int rc; 149 + 150 + rc = check_acpi_tpm2(dev); 151 + if (rc) 152 + return rc; 192 153 193 154 phy = devm_kzalloc(dev, sizeof(struct tpm_tis_tcg_phy), GFP_KERNEL); 194 155 if (phy == NULL) ··· 205 158 if (interrupts) 206 159 irq = tpm_info->irq; 207 160 208 - if (itpm) 161 + if (itpm || is_itpm(ACPI_COMPANION(dev))) 209 162 phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND; 210 163 211 164 return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg, 212 - acpi_dev_handle); 165 + ACPI_HANDLE(dev)); 213 166 } 214 167 215 168 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); ··· 218 171 const struct pnp_device_id *pnp_id) 219 172 { 220 173 struct tpm_info tpm_info = {}; 221 - acpi_handle acpi_dev_handle = NULL; 222 174 struct resource *res; 223 175 224 176 res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0); ··· 230 184 else 231 185 tpm_info.irq = -1; 232 186 233 - if (pnp_acpi_device(pnp_dev)) { 234 - if (is_itpm(pnp_acpi_device(pnp_dev))) 235 - itpm = true; 236 - 237 - acpi_dev_handle = ACPI_HANDLE(&pnp_dev->dev); 238 - } 239 - 240 - return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle); 187 + return tpm_tis_init(&pnp_dev->dev, &tpm_info); 241 188 } 242 189 243 190 static struct pnp_device_id tpm_pnp_tbl[] = { ··· 270 231 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); 271 232 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 272 233 273 - #ifdef CONFIG_ACPI 274 - static int tpm_check_resource(struct acpi_resource *ares, void *data) 275 - { 276 - struct tpm_info *tpm_info = (struct tpm_info *) data; 277 - struct resource res; 278 - 279 - if (acpi_dev_resource_interrupt(ares, 0, &res)) 280 - tpm_info->irq = res.start; 281 - else if (acpi_dev_resource_memory(ares, &res)) { 282 - tpm_info->res = res; 283 - tpm_info->res.name = NULL; 284 - } 285 - 286 - return 1; 287 - } 288 - 289 - static int tpm_tis_acpi_init(struct acpi_device *acpi_dev) 290 - { 291 - struct acpi_table_tpm2 *tbl; 292 - acpi_status st; 293 - struct list_head resources; 294 - struct tpm_info tpm_info = {}; 295 - int ret; 296 - 297 - st = acpi_get_table(ACPI_SIG_TPM2, 1, 298 - (struct acpi_table_header **) &tbl); 299 - if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) { 300 - dev_err(&acpi_dev->dev, 301 - FW_BUG "failed to get TPM2 ACPI table\n"); 302 - return -EINVAL; 303 - } 304 - 305 - if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED) 306 - return -ENODEV; 307 - 308 - INIT_LIST_HEAD(&resources); 309 - tpm_info.irq = -1; 310 - ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource, 311 - &tpm_info); 312 - if (ret < 0) 313 - return ret; 314 - 315 - acpi_dev_free_resource_list(&resources); 316 - 317 - if (resource_type(&tpm_info.res) != IORESOURCE_MEM) { 318 - dev_err(&acpi_dev->dev, 319 - FW_BUG "TPM2 ACPI table does not define a memory resource\n"); 320 - return -EINVAL; 321 - } 322 - 323 - if (is_itpm(acpi_dev)) 324 - itpm = true; 325 - 326 - return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle); 327 - } 328 - 329 - static int tpm_tis_acpi_remove(struct acpi_device *dev) 330 - { 331 - struct tpm_chip *chip = dev_get_drvdata(&dev->dev); 332 - 333 - tpm_chip_unregister(chip); 334 - tpm_tis_remove(chip); 335 - 336 - return 0; 337 - } 338 - 339 - static struct acpi_device_id tpm_acpi_tbl[] = { 340 - {"MSFT0101", 0}, /* TPM 2.0 */ 341 - /* Add new here */ 342 - {"", 0}, /* User Specified */ 343 - {"", 0} /* Terminator */ 344 - }; 345 - MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl); 346 - 347 - static struct acpi_driver tis_acpi_driver = { 348 - .name = "tpm_tis", 349 - .ids = tpm_acpi_tbl, 350 - .ops = { 351 - .add = tpm_tis_acpi_init, 352 - .remove = tpm_tis_acpi_remove, 353 - }, 354 - .drv = { 355 - .pm = &tpm_tis_pm, 356 - }, 357 - }; 358 - #endif 359 - 360 234 static struct platform_device *force_pdev; 361 235 362 236 static int tpm_tis_plat_probe(struct platform_device *pdev) ··· 293 341 tpm_info.irq = 0; 294 342 } 295 343 296 - return tpm_tis_init(&pdev->dev, &tpm_info, NULL); 344 + return tpm_tis_init(&pdev->dev, &tpm_info); 297 345 } 298 346 299 347 static int tpm_tis_plat_remove(struct platform_device *pdev) ··· 321 369 .name = "tpm_tis", 322 370 .pm = &tpm_tis_pm, 323 371 .of_match_table = of_match_ptr(tis_of_platform_match), 372 + .acpi_match_table = ACPI_PTR(tpm_acpi_tbl), 324 373 }, 325 374 }; 326 375 ··· 364 411 if (rc) 365 412 goto err_platform; 366 413 367 - #ifdef CONFIG_ACPI 368 - rc = acpi_bus_register_driver(&tis_acpi_driver); 369 - if (rc) 370 - goto err_acpi; 371 - #endif 372 414 373 415 if (IS_ENABLED(CONFIG_PNP)) { 374 416 rc = pnp_register_driver(&tis_pnp_driver); ··· 374 426 return 0; 375 427 376 428 err_pnp: 377 - #ifdef CONFIG_ACPI 378 - acpi_bus_unregister_driver(&tis_acpi_driver); 379 - err_acpi: 380 - #endif 381 429 platform_driver_unregister(&tis_drv); 382 430 err_platform: 383 431 if (force_pdev) ··· 385 441 static void __exit cleanup_tis(void) 386 442 { 387 443 pnp_unregister_driver(&tis_pnp_driver); 388 - #ifdef CONFIG_ACPI 389 - acpi_bus_unregister_driver(&tis_acpi_driver); 390 - #endif 391 444 platform_driver_unregister(&tis_drv); 392 445 393 446 if (force_pdev)