1 /* 2 * Copyright (C) 2005, 2006 IBM Corporation 3 * Copyright (C) 2014, 2015 Intel Corporation 4 * 5 * Authors: 6 * Leendert van Doorn <leendert@watson.ibm.com> 7 * Kylene Hall <kjhall@us.ibm.com> 8 * 9 * Maintained by: <tpmdd-devel@lists.sourceforge.net> 10 * 11 * Device driver for TCG/TCPA TPM (trusted platform module). 12 * Specifications at www.trustedcomputinggroup.org 13 * 14 * This device driver implements the TPM interface as defined in 15 * the TCG TPM Interface Spec version 1.2, revision 1.0. 16 * 17 * This program is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU General Public License as 19 * published by the Free Software Foundation, version 2 of the 20 * License. 21 */ 22 #include <linux/init.h> 23 #include <linux/module.h> 24 #include <linux/moduleparam.h> 25 #include <linux/pnp.h> 26 #include <linux/slab.h> 27 #include <linux/interrupt.h> 28 #include <linux/wait.h> 29 #include <linux/acpi.h> 30 #include <linux/freezer.h> 31 #include <linux/of.h> 32 #include <linux/of_device.h> 33 #include "tpm.h" 34 #include "tpm_tis_core.h" 35 36 struct tpm_info { 37 struct resource res; 38 /* irq > 0 means: use irq $irq; 39 * irq = 0 means: autoprobe for an irq; 40 * irq = -1 means: no irq support 41 */ 42 int irq; 43 }; 44 45 struct tpm_tis_tcg_phy { 46 struct tpm_tis_data priv; 47 void __iomem *iobase; 48 }; 49 50 static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *data) 51 { 52 return container_of(data, struct tpm_tis_tcg_phy, priv); 53 } 54 55 static bool interrupts = true; 56 module_param(interrupts, bool, 0444); 57 MODULE_PARM_DESC(interrupts, "Enable interrupts"); 58 59 static bool itpm; 60 module_param(itpm, bool, 0444); 61 MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); 62 63 static bool force; 64 #ifdef CONFIG_X86 65 module_param(force, bool, 0444); 66 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); 67 #endif 68 69 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) 70 static int has_hid(struct acpi_device *dev, const char *hid) 71 { 72 struct acpi_hardware_id *id; 73 74 list_for_each_entry(id, &dev->pnp.ids, list) 75 if (!strcmp(hid, id->id)) 76 return 1; 77 78 return 0; 79 } 80 81 static inline int is_itpm(struct acpi_device *dev) 82 { 83 if (!dev) 84 return 0; 85 return has_hid(dev, "INTC0102"); 86 } 87 #else 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) 130 { 131 return 0; 132 } 133 #endif 134 135 #ifdef CONFIG_X86 136 #define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 137 #define ILB_REMAP_SIZE 0x100 138 #define LPC_CNTRL_REG_OFFSET 0x84 139 #define LPC_CLKRUN_EN (1 << 2) 140 141 static void __iomem *ilb_base_addr; 142 143 static inline bool is_bsw(void) 144 { 145 return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); 146 } 147 148 /** 149 * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running 150 */ 151 static void tpm_platform_begin_xfer(void) 152 { 153 u32 clkrun_val; 154 155 if (!is_bsw()) 156 return; 157 158 clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); 159 160 /* Disable LPC CLKRUN# */ 161 clkrun_val &= ~LPC_CLKRUN_EN; 162 iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); 163 164 /* 165 * Write any random value on port 0x80 which is on LPC, to make 166 * sure LPC clock is running before sending any TPM command. 167 */ 168 outb(0xCC, 0x80); 169 170 } 171 172 /** 173 * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off 174 */ 175 static void tpm_platform_end_xfer(void) 176 { 177 u32 clkrun_val; 178 179 if (!is_bsw()) 180 return; 181 182 clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); 183 184 /* Enable LPC CLKRUN# */ 185 clkrun_val |= LPC_CLKRUN_EN; 186 iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); 187 188 /* 189 * Write any random value on port 0x80 which is on LPC, to make 190 * sure LPC clock is running before sending any TPM command. 191 */ 192 outb(0xCC, 0x80); 193 194 } 195 #else 196 static inline bool is_bsw(void) 197 { 198 return false; 199 } 200 201 static void tpm_platform_begin_xfer(void) 202 { 203 } 204 205 static void tpm_platform_end_xfer(void) 206 { 207 } 208 #endif 209 210 static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 211 u8 *result) 212 { 213 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 214 215 tpm_platform_begin_xfer(); 216 217 while (len--) 218 *result++ = ioread8(phy->iobase + addr); 219 220 tpm_platform_end_xfer(); 221 222 return 0; 223 } 224 225 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 226 u8 *value) 227 { 228 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 229 230 tpm_platform_begin_xfer(); 231 232 while (len--) 233 iowrite8(*value++, phy->iobase + addr); 234 235 tpm_platform_end_xfer(); 236 237 return 0; 238 } 239 240 static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result) 241 { 242 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 243 244 tpm_platform_begin_xfer(); 245 246 *result = ioread16(phy->iobase + addr); 247 248 tpm_platform_end_xfer(); 249 250 return 0; 251 } 252 253 static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result) 254 { 255 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 256 257 tpm_platform_begin_xfer(); 258 259 *result = ioread32(phy->iobase + addr); 260 261 tpm_platform_end_xfer(); 262 263 return 0; 264 } 265 266 static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) 267 { 268 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 269 270 tpm_platform_begin_xfer(); 271 272 iowrite32(value, phy->iobase + addr); 273 274 tpm_platform_end_xfer(); 275 276 return 0; 277 } 278 279 static const struct tpm_tis_phy_ops tpm_tcg = { 280 .read_bytes = tpm_tcg_read_bytes, 281 .write_bytes = tpm_tcg_write_bytes, 282 .read16 = tpm_tcg_read16, 283 .read32 = tpm_tcg_read32, 284 .write32 = tpm_tcg_write32, 285 }; 286 287 static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info) 288 { 289 struct tpm_tis_tcg_phy *phy; 290 int irq = -1; 291 int rc; 292 293 rc = check_acpi_tpm2(dev); 294 if (rc) 295 return rc; 296 297 phy = devm_kzalloc(dev, sizeof(struct tpm_tis_tcg_phy), GFP_KERNEL); 298 if (phy == NULL) 299 return -ENOMEM; 300 301 phy->iobase = devm_ioremap_resource(dev, &tpm_info->res); 302 if (IS_ERR(phy->iobase)) 303 return PTR_ERR(phy->iobase); 304 305 if (interrupts) 306 irq = tpm_info->irq; 307 308 if (itpm || is_itpm(ACPI_COMPANION(dev))) 309 phy->priv.flags |= TPM_TIS_ITPM_WORKAROUND; 310 311 return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg, 312 ACPI_HANDLE(dev)); 313 } 314 315 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); 316 317 static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, 318 const struct pnp_device_id *pnp_id) 319 { 320 struct tpm_info tpm_info = {}; 321 struct resource *res; 322 323 res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0); 324 if (!res) 325 return -ENODEV; 326 tpm_info.res = *res; 327 328 if (pnp_irq_valid(pnp_dev, 0)) 329 tpm_info.irq = pnp_irq(pnp_dev, 0); 330 else 331 tpm_info.irq = -1; 332 333 return tpm_tis_init(&pnp_dev->dev, &tpm_info); 334 } 335 336 static struct pnp_device_id tpm_pnp_tbl[] = { 337 {"PNP0C31", 0}, /* TPM */ 338 {"ATM1200", 0}, /* Atmel */ 339 {"IFX0102", 0}, /* Infineon */ 340 {"BCM0101", 0}, /* Broadcom */ 341 {"BCM0102", 0}, /* Broadcom */ 342 {"NSC1200", 0}, /* National */ 343 {"ICO0102", 0}, /* Intel */ 344 /* Add new here */ 345 {"", 0}, /* User Specified */ 346 {"", 0} /* Terminator */ 347 }; 348 MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); 349 350 static void tpm_tis_pnp_remove(struct pnp_dev *dev) 351 { 352 struct tpm_chip *chip = pnp_get_drvdata(dev); 353 354 tpm_chip_unregister(chip); 355 tpm_tis_remove(chip); 356 } 357 358 static struct pnp_driver tis_pnp_driver = { 359 .name = "tpm_tis", 360 .id_table = tpm_pnp_tbl, 361 .probe = tpm_tis_pnp_init, 362 .remove = tpm_tis_pnp_remove, 363 .driver = { 364 .pm = &tpm_tis_pm, 365 }, 366 }; 367 368 #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 369 module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, 370 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); 371 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 372 373 static struct platform_device *force_pdev; 374 375 static int tpm_tis_plat_probe(struct platform_device *pdev) 376 { 377 struct tpm_info tpm_info = {}; 378 struct resource *res; 379 380 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 381 if (res == NULL) { 382 dev_err(&pdev->dev, "no memory resource defined\n"); 383 return -ENODEV; 384 } 385 tpm_info.res = *res; 386 387 tpm_info.irq = platform_get_irq(pdev, 0); 388 if (tpm_info.irq <= 0) { 389 if (pdev != force_pdev) 390 tpm_info.irq = -1; 391 else 392 /* When forcing auto probe the IRQ */ 393 tpm_info.irq = 0; 394 } 395 396 return tpm_tis_init(&pdev->dev, &tpm_info); 397 } 398 399 static int tpm_tis_plat_remove(struct platform_device *pdev) 400 { 401 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); 402 403 tpm_chip_unregister(chip); 404 tpm_tis_remove(chip); 405 406 return 0; 407 } 408 409 #ifdef CONFIG_OF 410 static const struct of_device_id tis_of_platform_match[] = { 411 {.compatible = "tcg,tpm-tis-mmio"}, 412 {}, 413 }; 414 MODULE_DEVICE_TABLE(of, tis_of_platform_match); 415 #endif 416 417 static struct platform_driver tis_drv = { 418 .probe = tpm_tis_plat_probe, 419 .remove = tpm_tis_plat_remove, 420 .driver = { 421 .name = "tpm_tis", 422 .pm = &tpm_tis_pm, 423 .of_match_table = of_match_ptr(tis_of_platform_match), 424 .acpi_match_table = ACPI_PTR(tpm_acpi_tbl), 425 }, 426 }; 427 428 static int tpm_tis_force_device(void) 429 { 430 struct platform_device *pdev; 431 static const struct resource x86_resources[] = { 432 { 433 .start = 0xFED40000, 434 .end = 0xFED40000 + TIS_MEM_LEN - 1, 435 .flags = IORESOURCE_MEM, 436 }, 437 }; 438 439 if (!force) 440 return 0; 441 442 /* The driver core will match the name tpm_tis of the device to 443 * the tpm_tis platform driver and complete the setup via 444 * tpm_tis_plat_probe 445 */ 446 pdev = platform_device_register_simple("tpm_tis", -1, x86_resources, 447 ARRAY_SIZE(x86_resources)); 448 if (IS_ERR(pdev)) 449 return PTR_ERR(pdev); 450 force_pdev = pdev; 451 452 return 0; 453 } 454 455 static int __init init_tis(void) 456 { 457 int rc; 458 459 rc = tpm_tis_force_device(); 460 if (rc) 461 goto err_force; 462 463 #ifdef CONFIG_X86 464 if (is_bsw()) 465 ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, 466 ILB_REMAP_SIZE); 467 #endif 468 rc = platform_driver_register(&tis_drv); 469 if (rc) 470 goto err_platform; 471 472 473 if (IS_ENABLED(CONFIG_PNP)) { 474 rc = pnp_register_driver(&tis_pnp_driver); 475 if (rc) 476 goto err_pnp; 477 } 478 479 return 0; 480 481 err_pnp: 482 platform_driver_unregister(&tis_drv); 483 err_platform: 484 if (force_pdev) 485 platform_device_unregister(force_pdev); 486 #ifdef CONFIG_X86 487 if (is_bsw()) 488 iounmap(ilb_base_addr); 489 #endif 490 err_force: 491 return rc; 492 } 493 494 static void __exit cleanup_tis(void) 495 { 496 pnp_unregister_driver(&tis_pnp_driver); 497 platform_driver_unregister(&tis_drv); 498 499 #ifdef CONFIG_X86 500 if (is_bsw()) 501 iounmap(ilb_base_addr); 502 #endif 503 if (force_pdev) 504 platform_device_unregister(force_pdev); 505 } 506 507 module_init(init_tis); 508 module_exit(cleanup_tis); 509 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); 510 MODULE_DESCRIPTION("TPM Driver"); 511 MODULE_VERSION("2.0"); 512 MODULE_LICENSE("GPL"); 513