aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2015-11-25 16:05:34 -0500
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2015-12-20 08:26:25 -0500
commit7ab4032fa579cd54be6a986a5cfd7f374b6bf02d (patch)
tree34c4f061235c5ea09cb13fd44384ed4ad041ab82 /drivers/char
parent25112048cd59930e23775cafb88e18cfb484892c (diff)
tpm_tis: Get rid of the duplicate IRQ probing code
The new code that works directly in tpm_tis_send is able to handle IRQ probing duties as well, so just use it for everything. Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Tested-by: Martin Wilck <Martin.Wilck@ts.fujitsu.com> Tested-by: Scot Doyle <lkml14@scotdoyle.com> Signed-off--by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Acked-by: Peter Huewe <peterhuewe@gmx.de>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/tpm/tpm_tis.c64
2 files changed, 20 insertions, 45 deletions
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index a4257a32964f..347fc615bcc9 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -138,7 +138,6 @@ struct tpm_vendor_specific {
138 unsigned long base; /* TPM base address */ 138 unsigned long base; /* TPM base address */
139 139
140 int irq; 140 int irq;
141 int probed_irq;
142 141
143 int region_size; 142 int region_size;
144 int have_region; 143 int have_region;
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 56a295d328c7..2580893de023 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -99,6 +99,7 @@ static struct tpm_info tis_default_info = {
99#define TPM_RID(l) (0x0F04 | ((l) << 12)) 99#define TPM_RID(l) (0x0F04 | ((l) << 12))
100 100
101struct priv_data { 101struct priv_data {
102 bool irq_probing;
102 bool irq_tested; 103 bool irq_tested;
103}; 104};
104 105
@@ -463,8 +464,9 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
463 msleep(1); 464 msleep(1);
464 if (!priv->irq_tested) { 465 if (!priv->irq_tested) {
465 disable_interrupts(chip); 466 disable_interrupts(chip);
466 dev_err(chip->pdev, 467 if (!priv->irq_probing)
467 FW_BUG "TPM interrupt not working, polling instead\n"); 468 dev_err(chip->pdev, FW_BUG
469 "TPM interrupt not working, polling instead\n");
468 } 470 }
469 priv->irq_tested = true; 471 priv->irq_tested = true;
470 return rc; 472 return rc;
@@ -570,26 +572,6 @@ static const struct tpm_class_ops tpm_tis = {
570 .req_canceled = tpm_tis_req_canceled, 572 .req_canceled = tpm_tis_req_canceled,
571}; 573};
572 574
573static irqreturn_t tis_int_probe(int irq, void *dev_id)
574{
575 struct tpm_chip *chip = dev_id;
576 u32 interrupt;
577
578 interrupt = ioread32(chip->vendor.iobase +
579 TPM_INT_STATUS(chip->vendor.locality));
580
581 if (interrupt == 0)
582 return IRQ_NONE;
583
584 chip->vendor.probed_irq = irq;
585
586 /* Clear interrupts handled with TPM_EOI */
587 iowrite32(interrupt,
588 chip->vendor.iobase +
589 TPM_INT_STATUS(chip->vendor.locality));
590 return IRQ_HANDLED;
591}
592
593static irqreturn_t tis_int_handler(int dummy, void *dev_id) 575static irqreturn_t tis_int_handler(int dummy, void *dev_id)
594{ 576{
595 struct tpm_chip *chip = dev_id; 577 struct tpm_chip *chip = dev_id;
@@ -772,13 +754,14 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
772 iowrite8(i, chip->vendor.iobase + 754 iowrite8(i, chip->vendor.iobase +
773 TPM_INT_VECTOR(chip->vendor.locality)); 755 TPM_INT_VECTOR(chip->vendor.locality));
774 if (devm_request_irq 756 if (devm_request_irq
775 (dev, i, tis_int_probe, IRQF_SHARED, 757 (dev, i, tis_int_handler, IRQF_SHARED,
776 chip->devname, chip) != 0) { 758 chip->devname, chip) != 0) {
777 dev_info(chip->pdev, 759 dev_info(chip->pdev,
778 "Unable to request irq: %d for probe\n", 760 "Unable to request irq: %d for probe\n",
779 i); 761 i);
780 continue; 762 continue;
781 } 763 }
764 chip->vendor.irq = i;
782 765
783 /* Clear all existing */ 766 /* Clear all existing */
784 iowrite32(ioread32 767 iowrite32(ioread32
@@ -792,7 +775,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
792 chip->vendor.iobase + 775 chip->vendor.iobase +
793 TPM_INT_ENABLE(chip->vendor.locality)); 776 TPM_INT_ENABLE(chip->vendor.locality));
794 777
795 chip->vendor.probed_irq = 0; 778 priv->irq_tested = false;
779 priv->irq_probing = true;
796 780
797 /* Generate Interrupts */ 781 /* Generate Interrupts */
798 if (chip->flags & TPM_CHIP_FLAG_TPM2) 782 if (chip->flags & TPM_CHIP_FLAG_TPM2)
@@ -800,26 +784,20 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
800 else 784 else
801 tpm_gen_interrupt(chip); 785 tpm_gen_interrupt(chip);
802 786
803 chip->vendor.irq = chip->vendor.probed_irq; 787 priv->irq_probing = false;
804
805 /* free_irq will call into tis_int_probe;
806 clear all irqs we haven't seen while doing
807 tpm_gen_interrupt */
808 iowrite32(ioread32
809 (chip->vendor.iobase +
810 TPM_INT_STATUS(chip->vendor.locality)),
811 chip->vendor.iobase +
812 TPM_INT_STATUS(chip->vendor.locality));
813
814 /* Turn off */
815 iowrite32(intmask,
816 chip->vendor.iobase +
817 TPM_INT_ENABLE(chip->vendor.locality));
818 788
819 devm_free_irq(dev, i, chip); 789 /* tpm_tis_send will either confirm the interrupt is
790 * working or it will call disable_irq which undoes
791 * all of the above.
792 */
793 if (chip->vendor.irq)
794 break;
820 } 795 }
796 if (!chip->vendor.irq)
797 iowrite8(irq_r, chip->vendor.iobase +
798 TPM_INT_VECTOR(chip->vendor.locality));
821 } 799 }
822 if (chip->vendor.irq) { 800 if (chip->vendor.irq && !priv->irq_tested) {
823 iowrite8(chip->vendor.irq, 801 iowrite8(chip->vendor.irq,
824 chip->vendor.iobase + 802 chip->vendor.iobase +
825 TPM_INT_VECTOR(chip->vendor.locality)); 803 TPM_INT_VECTOR(chip->vendor.locality));
@@ -843,9 +821,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
843 chip->vendor.iobase + 821 chip->vendor.iobase +
844 TPM_INT_ENABLE(chip->vendor.locality)); 822 TPM_INT_ENABLE(chip->vendor.locality));
845 } 823 }
846 } else if (irq_r != -1) 824 }
847 iowrite8(irq_r, chip->vendor.iobase +
848 TPM_INT_VECTOR(chip->vendor.locality));
849 825
850 if (tpm_get_timeouts(chip)) { 826 if (tpm_get_timeouts(chip)) {
851 dev_err(dev, "Could not get TPM timeouts and durations\n"); 827 dev_err(dev, "Could not get TPM timeouts and durations\n");