aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorKylene Jo Hall <kjhall@us.ibm.com>2006-07-14 03:24:31 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-15 00:53:55 -0400
commit9e323d3ee0ba9381af494641e1e87a8d372f916b (patch)
treedce8b6d7e14a5a1d89c346b44e87d26c2c382a59 /drivers/char
parentcab091eaa4952777d3183b6d7ce203a213cddc12 (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/char')
-rw-r--r--drivers/char/tpm/tpm_tis.c75
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;
432module_param(interrupts, bool, 0444); 432module_param(interrupts, bool, 0444);
433MODULE_PARM_DESC(interrupts, "Enable interrupts"); 433MODULE_PARM_DESC(interrupts, "Enable interrupts");
434 434
435static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, 435static 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
593static 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
598static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) 603static 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);
630MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 635MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
631 636
637static 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
645static struct platform_device *pdev;
646
647static int force;
648module_param(force, bool, 0444);
649MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
632static int __init init_tis(void) 650static 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
661module_init(init_tis); 698module_init(init_tis);