Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 424

kernel-2.6.18-238.el5.src.rpm

From: Stefan Assmann <sassmann@redhat.com>
Date: Tue, 12 Oct 2010 08:32:12 -0400
Subject: [char] tpm: pay attention to IRQ info from PNP in tpm_tis
Message-id: <4CB41D0C.7020304@redhat.com>
Patchwork-id: 28695
O-Subject: [RHEL 5.6 PATCH] tpm: pay attention to IRQ info from PNP
Bugzilla: 636760

Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=636760

Description:
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.

Fixes call traces seen during boot, similar to the following:
tpm_tis 00:0a: 1.2 TPM (device-id 0x0, rev-id 78)
IRQ handler type mismatch for IRQ 4

Call Trace:
 [<ffffffff800bd7a8>] setup_irq+0x1b7/0x1cf
 [<ffffffff88219000>] :tpm_tis:tis_int_probe+0x0/0x58
 [<ffffffff800bd870>] request_irq+0xb0/0xd6
 [<ffffffff8821981d>] :tpm_tis:tpm_tis_init+0x1dc/0x3fd
 [<ffffffff801a695f>] pnp_device_probe+0x7b/0x9e
 [<ffffffff801cba73>] driver_probe_device+0x52/0xaa
 [<ffffffff801cbba2>] __driver_attach+0x65/0xb6
 [<ffffffff801cbb3d>] __driver_attach+0x0/0xb6
 [<ffffffff801cb37a>] bus_for_each_dev+0x43/0x6e
 [<ffffffff801cafb6>] bus_add_driver+0x76/0x110
 [<ffffffff800a8f6e>] sys_init_module+0xaf/0x1f2
 [<ffffffff8005d116>] system_call+0x7e/0x83

tpm_tis 00:0a: Unable to request irq: 4 for probe
IRQ handler type mismatch for IRQ 8

Call Trace:
 [<ffffffff800bd7a8>] setup_irq+0x1b7/0x1cf
 [<ffffffff88219000>] :tpm_tis:tis_int_probe+0x0/0x58
 [<ffffffff800bd870>] request_irq+0xb0/0xd6
 [<ffffffff8821981d>] :tpm_tis:tpm_tis_init+0x1dc/0x3fd
 [<ffffffff801a695f>] pnp_device_probe+0x7b/0x9e
 [<ffffffff801cba73>] driver_probe_device+0x52/0xaa
 [<ffffffff801cbba2>] __driver_attach+0x65/0xb6
 [<ffffffff801cbb3d>] __driver_attach+0x0/0xb6
 [<ffffffff801cb37a>] bus_for_each_dev+0x43/0x6e
 [<ffffffff801cafb6>] bus_add_driver+0x76/0x110
 [<ffffffff800a8f6e>] sys_init_module+0xaf/0x1f2
 [<ffffffff8005d116>] system_call+0x7e/0x83

tpm_tis 00:0a: Unable to request irq: 8 for probe

Upstream Status:
http://git.kernel.org/linus/7917ff9a4cefd0500aa4a1b1942da96dbce6999f

Brew Build:
http://brewweb.devel.redhat.com/brew/taskinfo?taskID=2814377

Test Status:
Tested on intel-hermosabeach-01.rhts.eng.rdu.redhat.com which was showing a
trace similar to the one above. The trace is gone after applying the patch.

  Stefan

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index ede24a2..1f6f92a 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -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)
@@ -661,7 +665,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);
 		}