diff options
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index dc8c540391fd..939e51e119e6 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -14,7 +14,6 @@ | |||
14 | * License. | 14 | * License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <acpi/acpi_bus.h> | ||
18 | #include <linux/pnp.h> | 17 | #include <linux/pnp.h> |
19 | #include "tpm.h" | 18 | #include "tpm.h" |
20 | 19 | ||
@@ -29,9 +28,10 @@ | |||
29 | #define TPM_MAX_TRIES 5000 | 28 | #define TPM_MAX_TRIES 5000 |
30 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 | 29 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
31 | 30 | ||
32 | /* These values will be filled after ACPI-call */ | 31 | /* These values will be filled after PnP-call */ |
33 | static int TPM_INF_DATA = 0; | 32 | static int TPM_INF_DATA = 0; |
34 | static int TPM_INF_ADDR = 0; | 33 | static int TPM_INF_ADDR = 0; |
34 | static int pnp_registered = 0; | ||
35 | 35 | ||
36 | /* TPM header definitions */ | 36 | /* TPM header definitions */ |
37 | enum infineon_tpm_header { | 37 | enum infineon_tpm_header { |
@@ -356,24 +356,26 @@ static const struct pnp_device_id tpm_pnp_tbl[] = { | |||
356 | {"IFX0102", 0}, | 356 | {"IFX0102", 0}, |
357 | {"", 0} | 357 | {"", 0} |
358 | }; | 358 | }; |
359 | MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | ||
359 | 360 | ||
360 | static int __devinit tpm_inf_acpi_probe(struct pnp_dev *dev, | 361 | static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, |
361 | const struct pnp_device_id *dev_id) | 362 | const struct pnp_device_id *dev_id) |
362 | { | 363 | { |
363 | TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff); | 364 | if (pnp_port_valid(dev, 0)) { |
364 | TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff); | 365 | TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff); |
365 | tpm_inf.base = pnp_port_start(dev, 1); | 366 | TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff); |
366 | dev_info(&dev->dev, "Found %s with ID %s\n", | 367 | tpm_inf.base = pnp_port_start(dev, 1); |
367 | dev->name, dev_id->id); | 368 | dev_info(&dev->dev, "Found %s with ID %s\n", |
368 | if (!((tpm_inf.base >> 8) & 0xff)) | 369 | dev->name, dev_id->id); |
369 | tpm_inf.base = 0; | 370 | return 0; |
370 | return 0; | 371 | } |
372 | return -ENODEV; | ||
371 | } | 373 | } |
372 | 374 | ||
373 | static struct pnp_driver tpm_inf_pnp = { | 375 | static struct pnp_driver tpm_inf_pnp = { |
374 | .name = "tpm_inf_pnp", | 376 | .name = "tpm_inf_pnp", |
375 | .id_table = tpm_pnp_tbl, | 377 | .id_table = tpm_pnp_tbl, |
376 | .probe = tpm_inf_acpi_probe, | 378 | .probe = tpm_inf_pnp_probe, |
377 | }; | 379 | }; |
378 | 380 | ||
379 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | 381 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, |
@@ -386,19 +388,30 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
386 | int productid[2]; | 388 | int productid[2]; |
387 | char chipname[20]; | 389 | char chipname[20]; |
388 | 390 | ||
389 | if (pci_enable_device(pci_dev)) | 391 | rc = pci_enable_device(pci_dev); |
390 | return -EIO; | 392 | if (rc) |
393 | return rc; | ||
391 | 394 | ||
392 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); | 395 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); |
393 | 396 | ||
394 | /* read IO-ports from ACPI */ | 397 | /* read IO-ports from PnP */ |
395 | pnp_register_driver(&tpm_inf_pnp); | 398 | rc = pnp_register_driver(&tpm_inf_pnp); |
396 | pnp_unregister_driver(&tpm_inf_pnp); | 399 | if (rc < 0) { |
400 | dev_err(&pci_dev->dev, | ||
401 | "Error %x from pnp_register_driver!\n",rc); | ||
402 | goto error2; | ||
403 | } | ||
404 | if (!rc) { | ||
405 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); | ||
406 | goto error; | ||
407 | } else { | ||
408 | pnp_registered = 1; | ||
409 | } | ||
397 | 410 | ||
398 | /* Make sure, we have received valid config ports */ | 411 | /* Make sure, we have received valid config ports */ |
399 | if (!TPM_INF_ADDR) { | 412 | if (!TPM_INF_ADDR) { |
400 | pci_disable_device(pci_dev); | 413 | dev_err(&pci_dev->dev, "No valid IO-ports received!\n"); |
401 | return -EIO; | 414 | goto error; |
402 | } | 415 | } |
403 | 416 | ||
404 | /* query chip for its vendor, its version number a.s.o. */ | 417 | /* query chip for its vendor, its version number a.s.o. */ |
@@ -418,23 +431,21 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
418 | 431 | ||
419 | switch ((productid[0] << 8) | productid[1]) { | 432 | switch ((productid[0] << 8) | productid[1]) { |
420 | case 6: | 433 | case 6: |
421 | sprintf(chipname, " (SLD 9630 TT 1.1)"); | 434 | snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)"); |
422 | break; | 435 | break; |
423 | case 11: | 436 | case 11: |
424 | sprintf(chipname, " (SLB 9635 TT 1.2)"); | 437 | snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)"); |
425 | break; | 438 | break; |
426 | default: | 439 | default: |
427 | sprintf(chipname, " (unknown chip)"); | 440 | snprintf(chipname, sizeof(chipname), " (unknown chip)"); |
428 | break; | 441 | break; |
429 | } | 442 | } |
430 | chipname[19] = 0; | ||
431 | 443 | ||
432 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | 444 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { |
433 | 445 | ||
434 | if (tpm_inf.base == 0) { | 446 | if (tpm_inf.base == 0) { |
435 | dev_err(&pci_dev->dev, "No IO-ports found!\n"); | 447 | dev_err(&pci_dev->dev, "No IO-ports found!\n"); |
436 | pci_disable_device(pci_dev); | 448 | goto error; |
437 | return -EIO; | ||
438 | } | 449 | } |
439 | /* configure TPM with IO-ports */ | 450 | /* configure TPM with IO-ports */ |
440 | outb(IOLIMH, TPM_INF_ADDR); | 451 | outb(IOLIMH, TPM_INF_ADDR); |
@@ -452,8 +463,7 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
452 | dev_err(&pci_dev->dev, | 463 | dev_err(&pci_dev->dev, |
453 | "Could not set IO-ports to %04x\n", | 464 | "Could not set IO-ports to %04x\n", |
454 | tpm_inf.base); | 465 | tpm_inf.base); |
455 | pci_disable_device(pci_dev); | 466 | goto error; |
456 | return -EIO; | ||
457 | } | 467 | } |
458 | 468 | ||
459 | /* activate register */ | 469 | /* activate register */ |
@@ -479,14 +489,16 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
479 | productid[0], productid[1], chipname); | 489 | productid[0], productid[1], chipname); |
480 | 490 | ||
481 | rc = tpm_register_hardware(pci_dev, &tpm_inf); | 491 | rc = tpm_register_hardware(pci_dev, &tpm_inf); |
482 | if (rc < 0) { | 492 | if (rc < 0) |
483 | pci_disable_device(pci_dev); | 493 | goto error; |
484 | return -ENODEV; | ||
485 | } | ||
486 | return 0; | 494 | return 0; |
487 | } else { | 495 | } else { |
488 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); | 496 | dev_info(&pci_dev->dev, "No Infineon TPM found!\n"); |
497 | error: | ||
498 | pnp_unregister_driver(&tpm_inf_pnp); | ||
499 | error2: | ||
489 | pci_disable_device(pci_dev); | 500 | pci_disable_device(pci_dev); |
501 | pnp_registered = 0; | ||
490 | return -ENODEV; | 502 | return -ENODEV; |
491 | } | 503 | } |
492 | } | 504 | } |
@@ -521,6 +533,8 @@ static int __init init_inf(void) | |||
521 | 533 | ||
522 | static void __exit cleanup_inf(void) | 534 | static void __exit cleanup_inf(void) |
523 | { | 535 | { |
536 | if (pnp_registered) | ||
537 | pnp_unregister_driver(&tpm_inf_pnp); | ||
524 | pci_unregister_driver(&inf_pci_driver); | 538 | pci_unregister_driver(&inf_pci_driver); |
525 | } | 539 | } |
526 | 540 | ||