tpm_tis: restore IRQ vector in IO memory after failed probing
authorMartin Wilck <Martin.Wilck@ts.fujitsu.com>
Mon, 9 Nov 2015 14:38:50 +0000 (16:38 +0200)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Mon, 9 Nov 2015 15:52:54 +0000 (17:52 +0200)
If the probing finishes without success, it will leave the value 15 in
the TPM_IRQ_VECTOR register. If the driver is unloaded and reloaded, it
will "think" that the hardware had been programmed with IRQ 15, and will
not probe again.

This patch restores the original value in the IO memory if no IRQ is
probed.

Signed-off-by: Martin Wilck <Martin.Wilck@ts.fujitsu.com>
Acked-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Acked-by: Peter Huewe <PeterHuewe@gmx.de>
drivers/char/tpm/tpm_tis.c

index 19f9c7dc7bc0828064b9ea47c5850adfde992a80..65f7eecc45b01c489e2381b2311a95f2898527df 100644 (file)
@@ -645,6 +645,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
 {
        u32 vendor, intfcaps, intmask;
        int rc, i, irq_s, irq_e, probe;
+       int irq_r = -1;
        struct tpm_chip *chip;
        struct priv_data *priv;
 
@@ -751,6 +752,7 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
                irq_s =
                    ioread8(chip->vendor.iobase +
                            TPM_INT_VECTOR(chip->vendor.locality));
+               irq_r = irq_s;
                if (irq_s) {
                        irq_e = irq_s;
                } else {
@@ -833,7 +835,9 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
                                  chip->vendor.iobase +
                                  TPM_INT_ENABLE(chip->vendor.locality));
                }
-       }
+       } else if (irq_r != -1)
+               iowrite8(irq_r, chip->vendor.iobase +
+                        TPM_INT_VECTOR(chip->vendor.locality));
 
        if (chip->flags & TPM_CHIP_FLAG_TPM2) {
                chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);