aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/tpm/tpm_tis.c33
2 files changed, 28 insertions, 6 deletions
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index c5e01c556233..9c4163cfa3ce 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -71,6 +71,7 @@ struct tpm_vendor_specific {
71 unsigned long base; /* TPM base address */ 71 unsigned long base; /* TPM base address */
72 72
73 int irq; 73 int irq;
74 int probed_irq;
74 75
75 int region_size; 76 int region_size;
76 int have_region; 77 int have_region;
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index b97ce2b205d7..47517e49d2be 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -438,7 +438,7 @@ static irqreturn_t tis_int_probe(int irq, void *dev_id)
438 if (interrupt == 0) 438 if (interrupt == 0)
439 return IRQ_NONE; 439 return IRQ_NONE;
440 440
441 chip->vendor.irq = irq; 441 chip->vendor.probed_irq = irq;
442 442
443 /* Clear interrupts handled with TPM_EOI */ 443 /* Clear interrupts handled with TPM_EOI */
444 iowrite32(interrupt, 444 iowrite32(interrupt,
@@ -486,7 +486,7 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
486 resource_size_t len, unsigned int irq) 486 resource_size_t len, unsigned int irq)
487{ 487{
488 u32 vendor, intfcaps, intmask; 488 u32 vendor, intfcaps, intmask;
489 int rc, i; 489 int rc, i, irq_s, irq_e;
490 struct tpm_chip *chip; 490 struct tpm_chip *chip;
491 491
492 if (!(chip = tpm_register_hardware(dev, &tpm_tis))) 492 if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
@@ -544,6 +544,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
544 if (intfcaps & TPM_INTF_DATA_AVAIL_INT) 544 if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
545 dev_dbg(dev, "\tData Avail Int Support\n"); 545 dev_dbg(dev, "\tData Avail Int Support\n");
546 546
547 /* get the timeouts before testing for irqs */
548 tpm_get_timeouts(chip);
549
547 /* INTERRUPT Setup */ 550 /* INTERRUPT Setup */
548 init_waitqueue_head(&chip->vendor.read_queue); 551 init_waitqueue_head(&chip->vendor.read_queue);
549 init_waitqueue_head(&chip->vendor.int_queue); 552 init_waitqueue_head(&chip->vendor.int_queue);
@@ -562,13 +565,19 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
562 if (interrupts) 565 if (interrupts)
563 chip->vendor.irq = irq; 566 chip->vendor.irq = irq;
564 if (interrupts && !chip->vendor.irq) { 567 if (interrupts && !chip->vendor.irq) {
565 chip->vendor.irq = 568 irq_s =
566 ioread8(chip->vendor.iobase + 569 ioread8(chip->vendor.iobase +
567 TPM_INT_VECTOR(chip->vendor.locality)); 570 TPM_INT_VECTOR(chip->vendor.locality));
571 if (irq_s) {
572 irq_e = irq_s;
573 } else {
574 irq_s = 3;
575 irq_e = 15;
576 }
568 577
569 for (i = 3; i < 16 && chip->vendor.irq == 0; i++) { 578 for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) {
570 iowrite8(i, chip->vendor.iobase + 579 iowrite8(i, chip->vendor.iobase +
571 TPM_INT_VECTOR(chip->vendor.locality)); 580 TPM_INT_VECTOR(chip->vendor.locality));
572 if (request_irq 581 if (request_irq
573 (i, tis_int_probe, IRQF_SHARED, 582 (i, tis_int_probe, IRQF_SHARED,
574 chip->vendor.miscdev.name, chip) != 0) { 583 chip->vendor.miscdev.name, chip) != 0) {
@@ -590,9 +599,22 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
590 chip->vendor.iobase + 599 chip->vendor.iobase +
591 TPM_INT_ENABLE(chip->vendor.locality)); 600 TPM_INT_ENABLE(chip->vendor.locality));
592 601
602 chip->vendor.probed_irq = 0;
603
593 /* Generate Interrupts */ 604 /* Generate Interrupts */
594 tpm_gen_interrupt(chip); 605 tpm_gen_interrupt(chip);
595 606
607 chip->vendor.irq = chip->vendor.probed_irq;
608
609 /* free_irq will call into tis_int_probe;
610 clear all irqs we haven't seen while doing
611 tpm_gen_interrupt */
612 iowrite32(ioread32
613 (chip->vendor.iobase +
614 TPM_INT_STATUS(chip->vendor.locality)),
615 chip->vendor.iobase +
616 TPM_INT_STATUS(chip->vendor.locality));
617
596 /* Turn off */ 618 /* Turn off */
597 iowrite32(intmask, 619 iowrite32(intmask,
598 chip->vendor.iobase + 620 chip->vendor.iobase +
@@ -631,7 +653,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
631 list_add(&chip->vendor.list, &tis_chips); 653 list_add(&chip->vendor.list, &tis_chips);
632 spin_unlock(&tis_lock); 654 spin_unlock(&tis_lock);
633 655
634 tpm_get_timeouts(chip);
635 tpm_continue_selftest(chip); 656 tpm_continue_selftest(chip);
636 657
637 return 0; 658 return 0;