diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 78 |
1 files changed, 43 insertions, 35 deletions
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 398514745d3f..447f76388067 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -16,6 +16,9 @@ | |||
16 | * published by the Free Software Foundation, version 2 of the | 16 | * published by the Free Software Foundation, version 2 of the |
17 | * License. | 17 | * License. |
18 | */ | 18 | */ |
19 | #include <linux/init.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/moduleparam.h> | ||
19 | #include <linux/pnp.h> | 22 | #include <linux/pnp.h> |
20 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
21 | #include <linux/wait.h> | 24 | #include <linux/wait.h> |
@@ -424,6 +427,10 @@ static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
424 | return IRQ_HANDLED; | 427 | return IRQ_HANDLED; |
425 | } | 428 | } |
426 | 429 | ||
430 | static int interrupts = 1; | ||
431 | module_param(interrupts, bool, 0444); | ||
432 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | ||
433 | |||
427 | static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | 434 | static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, |
428 | const struct pnp_device_id *pnp_id) | 435 | const struct pnp_device_id *pnp_id) |
429 | { | 436 | { |
@@ -510,44 +517,44 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
510 | iowrite32(intmask, | 517 | iowrite32(intmask, |
511 | chip->vendor.iobase + | 518 | chip->vendor.iobase + |
512 | TPM_INT_ENABLE(chip->vendor.locality)); | 519 | TPM_INT_ENABLE(chip->vendor.locality)); |
520 | if (interrupts) { | ||
521 | chip->vendor.irq = | ||
522 | ioread8(chip->vendor.iobase + | ||
523 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
524 | |||
525 | for (i = 3; i < 16 && chip->vendor.irq == 0; i++) { | ||
526 | iowrite8(i, chip->vendor.iobase + | ||
527 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
528 | if (request_irq | ||
529 | (i, tis_int_probe, SA_SHIRQ, | ||
530 | chip->vendor.miscdev.name, chip) != 0) { | ||
531 | dev_info(chip->dev, | ||
532 | "Unable to request irq: %d for probe\n", | ||
533 | i); | ||
534 | continue; | ||
535 | } | ||
513 | 536 | ||
514 | chip->vendor.irq = | 537 | /* Clear all existing */ |
515 | ioread8(chip->vendor.iobase + | 538 | iowrite32(ioread32 |
516 | TPM_INT_VECTOR(chip->vendor.locality)); | 539 | (chip->vendor.iobase + |
517 | 540 | TPM_INT_STATUS(chip->vendor.locality)), | |
518 | for (i = 3; i < 16 && chip->vendor.irq == 0; i++) { | 541 | chip->vendor.iobase + |
519 | iowrite8(i, | 542 | TPM_INT_STATUS(chip->vendor.locality)); |
520 | chip->vendor.iobase + | ||
521 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
522 | if (request_irq | ||
523 | (i, tis_int_probe, SA_SHIRQ, | ||
524 | chip->vendor.miscdev.name, chip) != 0) { | ||
525 | dev_info(chip->dev, | ||
526 | "Unable to request irq: %d for probe\n", | ||
527 | i); | ||
528 | continue; | ||
529 | } | ||
530 | |||
531 | /* Clear all existing */ | ||
532 | iowrite32(ioread32 | ||
533 | (chip->vendor.iobase + | ||
534 | TPM_INT_STATUS(chip->vendor.locality)), | ||
535 | chip->vendor.iobase + | ||
536 | TPM_INT_STATUS(chip->vendor.locality)); | ||
537 | 543 | ||
538 | /* Turn on */ | 544 | /* Turn on */ |
539 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, | 545 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, |
540 | chip->vendor.iobase + | 546 | chip->vendor.iobase + |
541 | TPM_INT_ENABLE(chip->vendor.locality)); | 547 | TPM_INT_ENABLE(chip->vendor.locality)); |
542 | 548 | ||
543 | /* Generate Interrupts */ | 549 | /* Generate Interrupts */ |
544 | tpm_gen_interrupt(chip); | 550 | tpm_gen_interrupt(chip); |
545 | 551 | ||
546 | /* Turn off */ | 552 | /* Turn off */ |
547 | iowrite32(intmask, | 553 | iowrite32(intmask, |
548 | chip->vendor.iobase + | 554 | chip->vendor.iobase + |
549 | TPM_INT_ENABLE(chip->vendor.locality)); | 555 | TPM_INT_ENABLE(chip->vendor.locality)); |
550 | free_irq(i, chip); | 556 | free_irq(i, chip); |
557 | } | ||
551 | } | 558 | } |
552 | if (chip->vendor.irq) { | 559 | if (chip->vendor.irq) { |
553 | iowrite8(chip->vendor.irq, | 560 | iowrite8(chip->vendor.irq, |
@@ -557,7 +564,8 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | |||
557 | (chip->vendor.irq, tis_int_handler, SA_SHIRQ, | 564 | (chip->vendor.irq, tis_int_handler, SA_SHIRQ, |
558 | chip->vendor.miscdev.name, chip) != 0) { | 565 | chip->vendor.miscdev.name, chip) != 0) { |
559 | dev_info(chip->dev, | 566 | dev_info(chip->dev, |
560 | "Unable to request irq: %d for use\n", i); | 567 | "Unable to request irq: %d for use\n", |
568 | chip->vendor.irq); | ||
561 | chip->vendor.irq = 0; | 569 | chip->vendor.irq = 0; |
562 | } else { | 570 | } else { |
563 | /* Clear all existing */ | 571 | /* Clear all existing */ |