tpm: pay attention to IRQ info from PNP
Bjorn Helgaas [Wed, 17 Oct 2007 06:26:46 +0000 (23:26 -0700)]
If we discover the TIS TPM device via PNP, use the PNP IRQ information rather
than probing for an IRQ.  If PNP shows no IRQ, run the TPM in polling mode.

Tested-by: <valdis.kletnieks@vt.edu>
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Cc: Kylene Hall <kjhall@us.ibm.com>
Cc: <tpm@selhorst.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

drivers/char/tpm/tpm_tis.c

index 23fa18a..a8e8084 100644 (file)
@@ -435,17 +435,12 @@ module_param(interrupts, bool, 0444);
 MODULE_PARM_DESC(interrupts, "Enable interrupts");
 
 static int tpm_tis_init(struct device *dev, resource_size_t start,
-                       resource_size_t len)
+                       resource_size_t len, unsigned int irq)
 {
        u32 vendor, intfcaps, intmask;
        int rc, i;
        struct tpm_chip *chip;
 
-       if (!start)
-               start = TIS_MEM_BASE;
-       if (!len)
-               len = TIS_MEM_LEN;
-
        if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
                return -ENODEV;
 
@@ -512,7 +507,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
        iowrite32(intmask,
                  chip->vendor.iobase +
                  TPM_INT_ENABLE(chip->vendor.locality));
-       if (interrupts) {
+       if (interrupts)
+               chip->vendor.irq = irq;
+       if (interrupts && !chip->vendor.irq) {
                chip->vendor.irq =
                    ioread8(chip->vendor.iobase +
                            TPM_INT_VECTOR(chip->vendor.locality));
@@ -597,10 +594,17 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
                                      const struct pnp_device_id *pnp_id)
 {
        resource_size_t start, len;
+       unsigned int irq = 0;
+
        start = pnp_mem_start(pnp_dev, 0);
        len = pnp_mem_len(pnp_dev, 0);
 
-       return tpm_tis_init(&pnp_dev->dev, start, len);
+       if (pnp_irq_valid(pnp_dev, 0))
+               irq = pnp_irq(pnp_dev, 0);
+       else
+               interrupts = 0;
+
+       return tpm_tis_init(&pnp_dev->dev, start, len, irq);
 }
 
 static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
@@ -660,7 +664,7 @@ static int __init init_tis(void)
                        return rc;
                if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
                        return PTR_ERR(pdev);
-               if((rc=tpm_tis_init(&pdev->dev, 0, 0)) != 0) {
+               if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
                        platform_device_unregister(pdev);
                        driver_unregister(&tis_drv);
                }