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 "tpm.h" 32 #include "tpm_tis_core.h" 33 34 struct tpm_info { 35 struct resource res; 36 /* irq > 0 means: use irq $irq; 37 * irq = 0 means: autoprobe for an irq; 38 * irq = -1 means: no irq support 39 */ 40 int irq; 41 }; 42 43 struct tpm_tis_tcg_phy { 44 struct tpm_tis_data priv; 45 void __iomem *iobase; 46 }; 47 48 static inline struct tpm_tis_tcg_phy *to_tpm_tis_tcg_phy(struct tpm_tis_data *data) 49 { 50 return container_of(data, struct tpm_tis_tcg_phy, priv); 51 } 52 53 static bool interrupts = true; 54 module_param(interrupts, bool, 0444); 55 MODULE_PARM_DESC(interrupts, "Enable interrupts"); 56 57 static bool itpm; 58 module_param(itpm, bool, 0444); 59 MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)"); 60 61 static bool force; 62 #ifdef CONFIG_X86 63 module_param(force, bool, 0444); 64 MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); 65 #endif 66 67 #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) 68 static int has_hid(struct acpi_device *dev, const char *hid) 69 { 70 struct acpi_hardware_id *id; 71 72 list_for_each_entry(id, &dev->pnp.ids, list) 73 if (!strcmp(hid, id->id)) 74 return 1; 75 76 return 0; 77 } 78 79 static inline int is_itpm(struct acpi_device *dev) 80 { 81 return has_hid(dev, "INTC0102"); 82 } 83 #else 84 static inline int is_itpm(struct acpi_device *dev) 85 { 86 return 0; 87 } 88 #endif 89 90 static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 91 u8 *result) 92 { 93 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 94 95 while (len--) 96 *result++ = ioread8(phy->iobase + addr); 97 return 0; 98 } 99 100 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, 101 u8 *value) 102 { 103 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 104 105 while (len--) 106 iowrite8(*value++, phy->iobase + addr); 107 return 0; 108 } 109 110 static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result) 111 { 112 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 113 114 *result = ioread16(phy->iobase + addr); 115 return 0; 116 } 117 118 static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result) 119 { 120 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 121 122 *result = ioread32(phy->iobase + addr); 123 return 0; 124 } 125 126 static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) 127 { 128 struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); 129 130 iowrite32(value, phy->iobase + addr); 131 return 0; 132 } 133 134 static const struct tpm_tis_phy_ops tpm_tcg = { 135 .read_bytes = tpm_tcg_read_bytes, 136 .write_bytes = tpm_tcg_write_bytes, 137 .read16 = tpm_tcg_read16, 138 .read32 = tpm_tcg_read32, 139 .write32 = tpm_tcg_write32, 140 }; 141 142 static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, 143 acpi_handle acpi_dev_handle) 144 { 145 struct tpm_tis_tcg_phy *phy; 146 int irq = -1; 147 148 phy = devm_kzalloc(dev, sizeof(struct tpm_tis_tcg_phy), GFP_KERNEL); 149 if (phy == NULL) 150 return -ENOMEM; 151 152 phy->iobase = devm_ioremap_resource(dev, &tpm_info->res); 153 if (IS_ERR(phy->iobase)) 154 return PTR_ERR(phy->iobase); 155 156 if (interrupts) 157 irq = tpm_info->irq; 158 159 if (itpm) 160 phy->priv.flags |= TPM_TIS_ITPM_POSSIBLE; 161 162 return tpm_tis_core_init(dev, &phy->priv, irq, &tpm_tcg, 163 acpi_dev_handle); 164 } 165 166 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); 167 168 static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, 169 const struct pnp_device_id *pnp_id) 170 { 171 struct tpm_info tpm_info = {}; 172 acpi_handle acpi_dev_handle = NULL; 173 struct resource *res; 174 175 res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0); 176 if (!res) 177 return -ENODEV; 178 tpm_info.res = *res; 179 180 if (pnp_irq_valid(pnp_dev, 0)) 181 tpm_info.irq = pnp_irq(pnp_dev, 0); 182 else 183 tpm_info.irq = -1; 184 185 if (pnp_acpi_device(pnp_dev)) { 186 if (is_itpm(pnp_acpi_device(pnp_dev))) 187 itpm = true; 188 189 acpi_dev_handle = ACPI_HANDLE(&pnp_dev->dev); 190 } 191 192 return tpm_tis_init(&pnp_dev->dev, &tpm_info, acpi_dev_handle); 193 } 194 195 static struct pnp_device_id tpm_pnp_tbl[] = { 196 {"PNP0C31", 0}, /* TPM */ 197 {"ATM1200", 0}, /* Atmel */ 198 {"IFX0102", 0}, /* Infineon */ 199 {"BCM0101", 0}, /* Broadcom */ 200 {"BCM0102", 0}, /* Broadcom */ 201 {"NSC1200", 0}, /* National */ 202 {"ICO0102", 0}, /* Intel */ 203 /* Add new here */ 204 {"", 0}, /* User Specified */ 205 {"", 0} /* Terminator */ 206 }; 207 MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); 208 209 static void tpm_tis_pnp_remove(struct pnp_dev *dev) 210 { 211 struct tpm_chip *chip = pnp_get_drvdata(dev); 212 213 tpm_chip_unregister(chip); 214 tpm_tis_remove(chip); 215 } 216 217 static struct pnp_driver tis_pnp_driver = { 218 .name = "tpm_tis", 219 .id_table = tpm_pnp_tbl, 220 .probe = tpm_tis_pnp_init, 221 .remove = tpm_tis_pnp_remove, 222 .driver = { 223 .pm = &tpm_tis_pm, 224 }, 225 }; 226 227 #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 228 module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, 229 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); 230 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 231 232 #ifdef CONFIG_ACPI 233 static int tpm_check_resource(struct acpi_resource *ares, void *data) 234 { 235 struct tpm_info *tpm_info = (struct tpm_info *) data; 236 struct resource res; 237 238 if (acpi_dev_resource_interrupt(ares, 0, &res)) 239 tpm_info->irq = res.start; 240 else if (acpi_dev_resource_memory(ares, &res)) { 241 tpm_info->res = res; 242 tpm_info->res.name = NULL; 243 } 244 245 return 1; 246 } 247 248 static int tpm_tis_acpi_init(struct acpi_device *acpi_dev) 249 { 250 struct acpi_table_tpm2 *tbl; 251 acpi_status st; 252 struct list_head resources; 253 struct tpm_info tpm_info = {}; 254 int ret; 255 256 st = acpi_get_table(ACPI_SIG_TPM2, 1, 257 (struct acpi_table_header **) &tbl); 258 if (ACPI_FAILURE(st) || tbl->header.length < sizeof(*tbl)) { 259 dev_err(&acpi_dev->dev, 260 FW_BUG "failed to get TPM2 ACPI table\n"); 261 return -EINVAL; 262 } 263 264 if (tbl->start_method != ACPI_TPM2_MEMORY_MAPPED) 265 return -ENODEV; 266 267 INIT_LIST_HEAD(&resources); 268 tpm_info.irq = -1; 269 ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource, 270 &tpm_info); 271 if (ret < 0) 272 return ret; 273 274 acpi_dev_free_resource_list(&resources); 275 276 if (resource_type(&tpm_info.res) != IORESOURCE_MEM) { 277 dev_err(&acpi_dev->dev, 278 FW_BUG "TPM2 ACPI table does not define a memory resource\n"); 279 return -EINVAL; 280 } 281 282 if (is_itpm(acpi_dev)) 283 itpm = true; 284 285 return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle); 286 } 287 288 static int tpm_tis_acpi_remove(struct acpi_device *dev) 289 { 290 struct tpm_chip *chip = dev_get_drvdata(&dev->dev); 291 292 tpm_chip_unregister(chip); 293 tpm_tis_remove(chip); 294 295 return 0; 296 } 297 298 static struct acpi_device_id tpm_acpi_tbl[] = { 299 {"MSFT0101", 0}, /* TPM 2.0 */ 300 /* Add new here */ 301 {"", 0}, /* User Specified */ 302 {"", 0} /* Terminator */ 303 }; 304 MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl); 305 306 static struct acpi_driver tis_acpi_driver = { 307 .name = "tpm_tis", 308 .ids = tpm_acpi_tbl, 309 .ops = { 310 .add = tpm_tis_acpi_init, 311 .remove = tpm_tis_acpi_remove, 312 }, 313 .drv = { 314 .pm = &tpm_tis_pm, 315 }, 316 }; 317 #endif 318 319 static struct platform_device *force_pdev; 320 321 static int tpm_tis_plat_probe(struct platform_device *pdev) 322 { 323 struct tpm_info tpm_info = {}; 324 struct resource *res; 325 326 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 327 if (res == NULL) { 328 dev_err(&pdev->dev, "no memory resource defined\n"); 329 return -ENODEV; 330 } 331 tpm_info.res = *res; 332 333 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 334 if (res) { 335 tpm_info.irq = res->start; 336 } else { 337 if (pdev == force_pdev) 338 tpm_info.irq = -1; 339 else 340 /* When forcing auto probe the IRQ */ 341 tpm_info.irq = 0; 342 } 343 344 return tpm_tis_init(&pdev->dev, &tpm_info, NULL); 345 } 346 347 static int tpm_tis_plat_remove(struct platform_device *pdev) 348 { 349 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); 350 351 tpm_chip_unregister(chip); 352 tpm_tis_remove(chip); 353 354 return 0; 355 } 356 357 static struct platform_driver tis_drv = { 358 .probe = tpm_tis_plat_probe, 359 .remove = tpm_tis_plat_remove, 360 .driver = { 361 .name = "tpm_tis", 362 .pm = &tpm_tis_pm, 363 }, 364 }; 365 366 static int tpm_tis_force_device(void) 367 { 368 struct platform_device *pdev; 369 static const struct resource x86_resources[] = { 370 { 371 .start = 0xFED40000, 372 .end = 0xFED40000 + TIS_MEM_LEN - 1, 373 .flags = IORESOURCE_MEM, 374 }, 375 }; 376 377 if (!force) 378 return 0; 379 380 /* The driver core will match the name tpm_tis of the device to 381 * the tpm_tis platform driver and complete the setup via 382 * tpm_tis_plat_probe 383 */ 384 pdev = platform_device_register_simple("tpm_tis", -1, x86_resources, 385 ARRAY_SIZE(x86_resources)); 386 if (IS_ERR(pdev)) 387 return PTR_ERR(pdev); 388 force_pdev = pdev; 389 390 return 0; 391 } 392 393 static int __init init_tis(void) 394 { 395 int rc; 396 397 rc = tpm_tis_force_device(); 398 if (rc) 399 goto err_force; 400 401 rc = platform_driver_register(&tis_drv); 402 if (rc) 403 goto err_platform; 404 405 #ifdef CONFIG_ACPI 406 rc = acpi_bus_register_driver(&tis_acpi_driver); 407 if (rc) 408 goto err_acpi; 409 #endif 410 411 if (IS_ENABLED(CONFIG_PNP)) { 412 rc = pnp_register_driver(&tis_pnp_driver); 413 if (rc) 414 goto err_pnp; 415 } 416 417 return 0; 418 419 err_pnp: 420 #ifdef CONFIG_ACPI 421 acpi_bus_unregister_driver(&tis_acpi_driver); 422 err_acpi: 423 #endif 424 platform_device_unregister(force_pdev); 425 err_platform: 426 if (force_pdev) 427 platform_device_unregister(force_pdev); 428 err_force: 429 return rc; 430 } 431 432 static void __exit cleanup_tis(void) 433 { 434 pnp_unregister_driver(&tis_pnp_driver); 435 #ifdef CONFIG_ACPI 436 acpi_bus_unregister_driver(&tis_acpi_driver); 437 #endif 438 platform_driver_unregister(&tis_drv); 439 440 if (force_pdev) 441 platform_device_unregister(force_pdev); 442 } 443 444 module_init(init_tis); 445 module_exit(cleanup_tis); 446 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); 447 MODULE_DESCRIPTION("TPM Driver"); 448 MODULE_VERSION("2.0"); 449 MODULE_LICENSE("GPL"); 450