diff options
author | Kylene Jo Hall <kjhall@us.ibm.com> | 2006-07-14 03:24:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-15 00:53:55 -0400 |
commit | 9e323d3ee0ba9381af494641e1e87a8d372f916b (patch) | |
tree | dce8b6d7e14a5a1d89c346b44e87d26c2c382a59 /drivers | |
parent | cab091eaa4952777d3183b6d7ce203a213cddc12 (diff) |
[PATCH] tpm: Add force device probe option
Some machine manufacturers are not sticking to the TCG specifications and
including an ACPI DSDT entry for the TPM which allows PNP discovery of the
device.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 75 |
1 files changed, 56 insertions, 19 deletions
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 29dac1e4537c..4d0df3324e4f 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -432,23 +432,18 @@ static int interrupts = 1; | |||
432 | module_param(interrupts, bool, 0444); | 432 | module_param(interrupts, bool, 0444); |
433 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | 433 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
434 | 434 | ||
435 | static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | 435 | static int tpm_tis_init(struct device *dev, unsigned long start, unsigned long len) |
436 | const struct pnp_device_id *pnp_id) | ||
437 | { | 436 | { |
438 | u32 vendor, intfcaps, intmask; | 437 | u32 vendor, intfcaps, intmask; |
439 | int rc, i; | 438 | int rc, i; |
440 | unsigned long start, len; | ||
441 | struct tpm_chip *chip; | 439 | struct tpm_chip *chip; |
442 | 440 | ||
443 | start = pnp_mem_start(pnp_dev, 0); | ||
444 | len = pnp_mem_len(pnp_dev, 0); | ||
445 | |||
446 | if (!start) | 441 | if (!start) |
447 | start = TIS_MEM_BASE; | 442 | start = TIS_MEM_BASE; |
448 | if (!len) | 443 | if (!len) |
449 | len = TIS_MEM_LEN; | 444 | len = TIS_MEM_LEN; |
450 | 445 | ||
451 | if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis))) | 446 | if (!(chip = tpm_register_hardware(dev, &tpm_tis))) |
452 | return -ENODEV; | 447 | return -ENODEV; |
453 | 448 | ||
454 | chip->vendor.iobase = ioremap(start, len); | 449 | chip->vendor.iobase = ioremap(start, len); |
@@ -465,7 +460,7 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
465 | chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | 460 | chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); |
466 | chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | 461 | chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); |
467 | 462 | ||
468 | dev_info(&pnp_dev->dev, | 463 | dev_info(dev, |
469 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", | 464 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", |
470 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); | 465 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); |
471 | 466 | ||
@@ -473,26 +468,26 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
473 | intfcaps = | 468 | intfcaps = |
474 | ioread32(chip->vendor.iobase + | 469 | ioread32(chip->vendor.iobase + |
475 | TPM_INTF_CAPS(chip->vendor.locality)); | 470 | TPM_INTF_CAPS(chip->vendor.locality)); |
476 | dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n", | 471 | dev_dbg(dev, "TPM interface capabilities (0x%x):\n", |
477 | intfcaps); | 472 | intfcaps); |
478 | if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) | 473 | if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) |
479 | dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n"); | 474 | dev_dbg(dev, "\tBurst Count Static\n"); |
480 | if (intfcaps & TPM_INTF_CMD_READY_INT) | 475 | if (intfcaps & TPM_INTF_CMD_READY_INT) |
481 | dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n"); | 476 | dev_dbg(dev, "\tCommand Ready Int Support\n"); |
482 | if (intfcaps & TPM_INTF_INT_EDGE_FALLING) | 477 | if (intfcaps & TPM_INTF_INT_EDGE_FALLING) |
483 | dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n"); | 478 | dev_dbg(dev, "\tInterrupt Edge Falling\n"); |
484 | if (intfcaps & TPM_INTF_INT_EDGE_RISING) | 479 | if (intfcaps & TPM_INTF_INT_EDGE_RISING) |
485 | dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n"); | 480 | dev_dbg(dev, "\tInterrupt Edge Rising\n"); |
486 | if (intfcaps & TPM_INTF_INT_LEVEL_LOW) | 481 | if (intfcaps & TPM_INTF_INT_LEVEL_LOW) |
487 | dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n"); | 482 | dev_dbg(dev, "\tInterrupt Level Low\n"); |
488 | if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) | 483 | if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) |
489 | dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n"); | 484 | dev_dbg(dev, "\tInterrupt Level High\n"); |
490 | if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) | 485 | if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) |
491 | dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n"); | 486 | dev_dbg(dev, "\tLocality Change Int Support\n"); |
492 | if (intfcaps & TPM_INTF_STS_VALID_INT) | 487 | if (intfcaps & TPM_INTF_STS_VALID_INT) |
493 | dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n"); | 488 | dev_dbg(dev, "\tSts Valid Int Support\n"); |
494 | if (intfcaps & TPM_INTF_DATA_AVAIL_INT) | 489 | if (intfcaps & TPM_INTF_DATA_AVAIL_INT) |
495 | dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n"); | 490 | dev_dbg(dev, "\tData Avail Int Support\n"); |
496 | 491 | ||
497 | if (request_locality(chip, 0) != 0) { | 492 | if (request_locality(chip, 0) != 0) { |
498 | rc = -ENODEV; | 493 | rc = -ENODEV; |
@@ -595,6 +590,16 @@ out_err: | |||
595 | return rc; | 590 | return rc; |
596 | } | 591 | } |
597 | 592 | ||
593 | static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | ||
594 | const struct pnp_device_id *pnp_id) | ||
595 | { | ||
596 | unsigned long start, len; | ||
597 | start = pnp_mem_start(pnp_dev, 0); | ||
598 | len = pnp_mem_len(pnp_dev, 0); | ||
599 | |||
600 | return tpm_tis_init(&pnp_dev->dev, start, len); | ||
601 | } | ||
602 | |||
598 | static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) | 603 | static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) |
599 | { | 604 | { |
600 | return tpm_pm_suspend(&dev->dev, msg); | 605 | return tpm_pm_suspend(&dev->dev, msg); |
@@ -629,8 +634,36 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | |||
629 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); | 634 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); |
630 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | 635 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); |
631 | 636 | ||
637 | static struct device_driver tis_drv = { | ||
638 | .name = "tpm_tis", | ||
639 | .bus = &platform_bus_type, | ||
640 | .owner = THIS_MODULE, | ||
641 | .suspend = tpm_pm_suspend, | ||
642 | .resume = tpm_pm_resume, | ||
643 | }; | ||
644 | |||
645 | static struct platform_device *pdev; | ||
646 | |||
647 | static int force; | ||
648 | module_param(force, bool, 0444); | ||
649 | MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry"); | ||
632 | static int __init init_tis(void) | 650 | static int __init init_tis(void) |
633 | { | 651 | { |
652 | int rc; | ||
653 | |||
654 | if (force) { | ||
655 | rc = driver_register(&tis_drv); | ||
656 | if (rc < 0) | ||
657 | return rc; | ||
658 | if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0))) | ||
659 | return PTR_ERR(pdev); | ||
660 | if((rc=tpm_tis_init(&pdev->dev, 0, 0)) != 0) { | ||
661 | platform_device_unregister(pdev); | ||
662 | driver_unregister(&tis_drv); | ||
663 | } | ||
664 | return rc; | ||
665 | } | ||
666 | |||
634 | return pnp_register_driver(&tis_pnp_driver); | 667 | return pnp_register_driver(&tis_pnp_driver); |
635 | } | 668 | } |
636 | 669 | ||
@@ -655,7 +688,11 @@ static void __exit cleanup_tis(void) | |||
655 | tpm_remove_hardware(chip->dev); | 688 | tpm_remove_hardware(chip->dev); |
656 | } | 689 | } |
657 | spin_unlock(&tis_lock); | 690 | spin_unlock(&tis_lock); |
658 | pnp_unregister_driver(&tis_pnp_driver); | 691 | if (force) { |
692 | platform_device_unregister(pdev); | ||
693 | driver_unregister(&tis_drv); | ||
694 | } else | ||
695 | pnp_unregister_driver(&tis_pnp_driver); | ||
659 | } | 696 | } |
660 | 697 | ||
661 | module_init(init_tis); | 698 | module_init(init_tis); |