X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=drivers%2Fchar%2Ftpm%2Ftpm_tis.c;h=56a295d328c73476109d86f2b920ac4d5b82dd08;hb=25112048cd59930e23775cafb88e18cfb484892c;hp=696ef1d56b4f5830682bc1227b72686c2906eefb;hpb=2df4ee78d042ee3d17cbebd51e31b300286549dc;p=cascardo%2Flinux.git diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 696ef1d56b4f..56a295d328c7 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -401,7 +401,7 @@ static void disable_interrupts(struct tpm_chip *chip) iowrite32(intmask, chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); - free_irq(chip->vendor.irq, chip); + devm_free_irq(chip->pdev, chip->vendor.irq, chip); chip->vendor.irq = 0; } @@ -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; @@ -676,6 +677,15 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, goto out_err; } + /* Take control of the TPM's interrupt hardware and shut it off */ + intmask = ioread32(chip->vendor.iobase + + TPM_INT_ENABLE(chip->vendor.locality)); + intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | + TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; + intmask &= ~TPM_GLOBAL_INT_ENABLE; + iowrite32(intmask, + chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); + if (request_locality(chip, 0) != 0) { rc = -ENODEV; goto out_err; @@ -730,27 +740,27 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, if (intfcaps & TPM_INTF_DATA_AVAIL_INT) dev_dbg(dev, "\tData Avail Int Support\n"); + /* Very early on issue a command to the TPM in polling mode to make + * sure it works. May as well use that command to set the proper + * timeouts for the driver. + */ + if (tpm_get_timeouts(chip)) { + dev_err(dev, "Could not get TPM timeouts and durations\n"); + rc = -ENODEV; + goto out_err; + } + /* INTERRUPT Setup */ init_waitqueue_head(&chip->vendor.read_queue); init_waitqueue_head(&chip->vendor.int_queue); - intmask = - ioread32(chip->vendor.iobase + - TPM_INT_ENABLE(chip->vendor.locality)); - - intmask |= TPM_INTF_CMD_READY_INT - | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT - | TPM_INTF_STS_VALID_INT; - - iowrite32(intmask, - chip->vendor.iobase + - TPM_INT_ENABLE(chip->vendor.locality)); if (interrupts) chip->vendor.irq = tpm_info->irq; if (interrupts && !chip->vendor.irq) { irq_s = ioread8(chip->vendor.iobase + TPM_INT_VECTOR(chip->vendor.locality)); + irq_r = irq_s; if (irq_s) { irq_e = irq_s; } else { @@ -805,6 +815,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, iowrite32(intmask, chip->vendor.iobase + TPM_INT_ENABLE(chip->vendor.locality)); + + devm_free_irq(dev, i, chip); } } if (chip->vendor.irq) { @@ -831,20 +843,17 @@ 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 (tpm_get_timeouts(chip)) { + dev_err(dev, "Could not get TPM timeouts and durations\n"); + rc = -ENODEV; + goto out_err; } if (chip->flags & TPM_CHIP_FLAG_TPM2) { - chip->vendor.timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A); - chip->vendor.timeout_b = msecs_to_jiffies(TPM2_TIMEOUT_B); - chip->vendor.timeout_c = msecs_to_jiffies(TPM2_TIMEOUT_C); - chip->vendor.timeout_d = msecs_to_jiffies(TPM2_TIMEOUT_D); - chip->vendor.duration[TPM_SHORT] = - msecs_to_jiffies(TPM2_DURATION_SHORT); - chip->vendor.duration[TPM_MEDIUM] = - msecs_to_jiffies(TPM2_DURATION_MEDIUM); - chip->vendor.duration[TPM_LONG] = - msecs_to_jiffies(TPM2_DURATION_LONG); - rc = tpm2_do_selftest(chip); if (rc == TPM2_RC_INITIALIZE) { dev_warn(dev, "Firmware has not started TPM\n"); @@ -860,12 +869,6 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info, goto out_err; } } else { - if (tpm_get_timeouts(chip)) { - dev_err(dev, "Could not get TPM timeouts and durations\n"); - rc = -ENODEV; - goto out_err; - } - if (tpm_do_selftest(chip)) { dev_err(dev, "TPM self test failed\n"); rc = -ENODEV;