aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScot Doyle <lkml14@scotdoyle.com>2014-09-24 18:41:10 -0400
committerPeter Huewe <peterhuewe@gmx.de>2015-01-17 08:00:05 -0500
commit448e9c55c12d6bd4fa90a7e31d802e045666d7c8 (patch)
tree723a1174212ace1244c6dacd67f4450d8090bee5
parentbb95cd34ba4c9467114acc78eeddd53ab1c10085 (diff)
tpm_tis: verify interrupt during init
Some machines, such as the Acer C720 and Toshiba CB35, have TPMs that do not send IRQs while also having an ACPI TPM entry indicating that they will be sent. These machines freeze on resume while the tpm_tis module waits for an IRQ, eventually timing out. When in interrupt mode, the tpm_tis module should receive an IRQ during module init. Fall back to polling mode if none is received when expected. Cc: <stable@vger.kernel.org> Signed-off-by: Scot Doyle <lkml14@scotdoyle.com> Tested-by: Michael Mullin <masmullin@gmail.com> Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> [phuewe: minor checkpatch fixed] Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
-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);