aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tpm/tpm_tis.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 6f1985496112..ccb140d60532 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -75,6 +75,10 @@ enum tis_defaults {
75#define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) 75#define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
76#define TPM_RID(l) (0x0F04 | ((l) << 12)) 76#define TPM_RID(l) (0x0F04 | ((l) << 12))
77 77
78struct priv_data {
79 bool irq_tested;
80};
81
78static LIST_HEAD(tis_chips); 82static LIST_HEAD(tis_chips);
79static DEFINE_MUTEX(tis_lock); 83static DEFINE_MUTEX(tis_lock);
80 84
@@ -338,12 +342,27 @@ out_err:
338 return rc; 342 return rc;
339} 343}
340 344
345static void disable_interrupts(struct tpm_chip *chip)
346{
347 u32 intmask;
348
349 intmask =
350 ioread32(chip->vendor.iobase +
351 TPM_INT_ENABLE(chip->vendor.locality));
352 intmask &= ~TPM_GLOBAL_INT_ENABLE;
353 iowrite32(intmask,
354 chip->vendor.iobase +
355 TPM_INT_ENABLE(chip->vendor.locality));
356 free_irq(chip->vendor.irq, chip);
357 chip->vendor.irq = 0;
358}
359
341/* 360/*
342 * If interrupts are used (signaled by an irq set in the vendor structure) 361 * If interrupts are used (signaled by an irq set in the vendor structure)
343 * tpm.c can skip polling for the data to be available as the interrupt is 362 * tpm.c can skip polling for the data to be available as the interrupt is
344 * waited for here 363 * waited for here
345 */ 364 */
346static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) 365static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len)
347{ 366{
348 int rc; 367 int rc;
349 u32 ordinal; 368 u32 ordinal;
@@ -373,6 +392,30 @@ out_err:
373 return rc; 392 return rc;
374} 393}
375 394
395static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
396{
397 int rc, irq;
398 struct priv_data *priv = chip->vendor.priv;
399
400 if (!chip->vendor.irq || priv->irq_tested)
401 return tpm_tis_send_main(chip, buf, len);
402
403 /* Verify receipt of the expected IRQ */
404 irq = chip->vendor.irq;
405 chip->vendor.irq = 0;
406 rc = tpm_tis_send_main(chip, buf, len);
407 chip->vendor.irq = irq;
408 if (!priv->irq_tested)
409 msleep(1);
410 if (!priv->irq_tested) {
411 disable_interrupts(chip);
412 dev_err(chip->dev,
413 FW_BUG "TPM interrupt not working, polling instead\n");
414 }
415 priv->irq_tested = true;
416 return rc;
417}
418
376struct tis_vendor_timeout_override { 419struct tis_vendor_timeout_override {
377 u32 did_vid; 420 u32 did_vid;
378 unsigned long timeout_us[4]; 421 unsigned long timeout_us[4];
@@ -505,6 +548,7 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
505 if (interrupt == 0) 548 if (interrupt == 0)
506 return IRQ_NONE; 549 return IRQ_NONE;
507 550
551 ((struct priv_data *)chip->vendor.priv)->irq_tested = true;
508 if (interrupt & TPM_INTF_DATA_AVAIL_INT) 552 if (interrupt & TPM_INTF_DATA_AVAIL_INT)
509 wake_up_interruptible(&chip->vendor.read_queue); 553 wake_up_interruptible(&chip->vendor.read_queue);
510 if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT) 554 if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
@@ -534,9 +578,14 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
534 u32 vendor, intfcaps, intmask; 578 u32 vendor, intfcaps, intmask;
535 int rc, i, irq_s, irq_e, probe; 579 int rc, i, irq_s, irq_e, probe;
536 struct tpm_chip *chip; 580 struct tpm_chip *chip;
581 struct priv_data *priv;
537 582
583 priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL);
584 if (priv == NULL)
585 return -ENOMEM;
538 if (!(chip = tpm_register_hardware(dev, &tpm_tis))) 586 if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
539 return -ENODEV; 587 return -ENODEV;
588 chip->vendor.priv = priv;
540 589
541 chip->vendor.iobase = ioremap(start, len); 590 chip->vendor.iobase = ioremap(start, len);
542 if (!chip->vendor.iobase) { 591 if (!chip->vendor.iobase) {
@@ -605,19 +654,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
605 if (intfcaps & TPM_INTF_DATA_AVAIL_INT) 654 if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
606 dev_dbg(dev, "\tData Avail Int Support\n"); 655 dev_dbg(dev, "\tData Avail Int Support\n");
607 656
608 /* get the timeouts before testing for irqs */
609 if (tpm_get_timeouts(chip)) {
610 dev_err(dev, "Could not get TPM timeouts and durations\n");
611 rc = -ENODEV;
612 goto out_err;
613 }
614
615 if (tpm_do_selftest(chip)) {
616 dev_err(dev, "TPM self test failed\n");
617 rc = -ENODEV;
618 goto out_err;
619 }
620
621 /* INTERRUPT Setup */ 657 /* INTERRUPT Setup */
622 init_waitqueue_head(&chip->vendor.read_queue); 658 init_waitqueue_head(&chip->vendor.read_queue);
623 init_waitqueue_head(&chip->vendor.int_queue); 659 init_waitqueue_head(&chip->vendor.int_queue);
@@ -719,6 +755,18 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
719 } 755 }
720 } 756 }
721 757
758 if (tpm_get_timeouts(chip)) {
759 dev_err(dev, "Could not get TPM timeouts and durations\n");
760 rc = -ENODEV;
761 goto out_err;
762 }
763
764 if (tpm_do_selftest(chip)) {
765 dev_err(dev, "TPM self test failed\n");
766 rc = -ENODEV;
767 goto out_err;
768 }
769
722 INIT_LIST_HEAD(&chip->vendor.list); 770 INIT_LIST_HEAD(&chip->vendor.list);
723 mutex_lock(&tis_lock); 771 mutex_lock(&tis_lock);
724 list_add(&chip->vendor.list, &tis_chips); 772 list_add(&chip->vendor.list, &tis_chips);