All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andy Isaacson <adi@vmware.com>
To: linux-kernel@vger.kernel.org, tpmdd-devel@lists.sourceforge.net
Cc: adi@hexapodia.org, Rajiv Andrade <srajiv@linux.vnet.ibm.com>,
	dds@google.com, Mimi Zohar <zohar@linux.vnet.ibm.com>,
	Shahbaz Khan <shaz.linux@gmail.com>,
	seiji.munetoh@gmail.com, Andy Isaacson <adi@vmware.com>
Subject: [PATCH 5/6] tpm_tis: convert from pnp_driver to acpi_driver
Date: Tue, 30 Jun 2009 18:04:14 -0700	[thread overview]
Message-ID: <1246410255-6839-6-git-send-email-adi@vmware.com> (raw)
In-Reply-To: <1246410255-6839-1-git-send-email-adi@vmware.com>

Not all TIS-compatible TPM chips have a _HID method in their ACPI entry,
and the TPM spec says that the _CID method should be used to enumerate
the TPM chip.

Convert to acpi_driver so that we can access the _CID entry.

Signed-off-by: Andy Isaacson <adi@vmware.com>
---
 drivers/char/tpm/Kconfig   |    2 +-
 drivers/char/tpm/tpm_tis.c |  157 +++++++++++++++++++++++++++++++++----------
 2 files changed, 121 insertions(+), 38 deletions(-)

diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index f5fc64f..204b69f 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -24,7 +24,7 @@ if TCG_TPM
 
 config TCG_TIS
 	tristate "TPM Interface Specification 1.2 Interface"
-	depends on PNP
+	depends on ACPI
 	---help---
 	  If you have a TPM security chip that is compliant with the
 	  TCG TIS 1.2 TPM specification say Yes and it will be accessible
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 50c2a8a..7f0cb6c 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -21,9 +21,12 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/pnp.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
+
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
 #include "tpm.h"
 
 #define TPM_HEADER_SIZE 10
@@ -77,6 +80,13 @@ enum tis_defaults {
 static LIST_HEAD(tis_chips);
 static DEFINE_SPINLOCK(tis_lock);
 
+struct tpm_data {
+	unsigned long tpm_phys_address;
+	void __iomem *tpm_address;
+	int tpm_size;
+	int tpm_irq;
+};
+
 static int check_locality(struct tpm_chip *chip, int l)
 {
 	if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
@@ -590,34 +600,114 @@ out_err:
 	return rc;
 }
 
-static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
-				      const struct pnp_device_id *pnp_id)
+static acpi_status tpm_resources(struct acpi_resource *res, void *data)
+{
+	struct acpi_device *device = data;
+	struct device *dev = &device->dev;
+	struct tpm_data *tpm = device->driver_data;
+	acpi_status status;
+	struct acpi_resource_address64 addr;
+
+	status = acpi_resource_to_address64(res, &addr);
+
+	if (ACPI_SUCCESS(status)) {
+		dev_info(dev, "found 0x%llx(0x%llx)\n",
+				(long long)addr.minimum,
+				(long long)addr.address_length);
+		tpm->tpm_phys_address = addr.minimum;
+		tpm->tpm_address = ioremap(addr.minimum, addr.address_length);
+		tpm->tpm_size = addr.address_length;
+	} else if (res->type == ACPI_RESOURCE_TYPE_FIXED_MEMORY32) {
+		struct acpi_resource_fixed_memory32 *fixmem32;
+
+		fixmem32 = &res->data.fixed_memory32;
+		if (!fixmem32)
+			return AE_NO_MEMORY;
+
+		dev_info(dev, "found 0x%llx(0x%llx)\n",
+				(long long)fixmem32->address,
+				(long long)TIS_MEM_LEN);
+		tpm->tpm_phys_address = fixmem32->address;
+		tpm->tpm_address = ioremap(fixmem32->address, TIS_MEM_LEN);
+		tpm->tpm_size = fixmem32->address_length;
+	} else if (res->type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ) {
+		struct acpi_resource_extended_irq *irq;
+
+		irq = &res->data.extended_irq;
+		if (irq->interrupt_count > 0 && irq->interrupts[0] > 0) {
+			dev_info(dev, "IRQ %d (%d, %d)\n",
+					irq->interrupts[0],
+					irq->triggering, irq->polarity);
+			tpm->tpm_irq = irq->interrupts[0];
+		}
+	}
+
+	return AE_OK;
+}
+
+static int tpm_tis_acpi_add(struct acpi_device *device)
 {
-	resource_size_t start, len;
-	unsigned int irq = 0;
+	acpi_status result;
+	struct tpm_data *tpm = kzalloc(sizeof(*tpm), GFP_KERNEL);
+	int rc = -ENOMEM;
+
+	if (!tpm)
+		goto out;
 
-	start = pnp_mem_start(pnp_dev, 0);
-	len = pnp_mem_len(pnp_dev, 0);
+	device->driver_data = tpm;
+
+	result = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+			tpm_resources, device);
+
+	rc = -ENODEV;
+	if (ACPI_FAILURE(result))
+		goto out_free;
+
+	if (!tpm->tpm_address) {
+		dev_err(&device->dev, "no address found in _CRS\n");
+		goto out_free;
+	}
 
-	if (pnp_irq_valid(pnp_dev, 0))
-		irq = pnp_irq(pnp_dev, 0);
-	else
+	if (!tpm->tpm_irq) {
+		dev_err(&device->dev, "no IRQ found in _CRS, polling mode\n");
 		interrupts = 0;
+	}
 
-	return tpm_tis_init(&pnp_dev->dev, start, len, irq);
+	return tpm_tis_init(&device->dev, tpm->tpm_phys_address, tpm->tpm_size,
+			tpm->tpm_irq);
+out_free:
+	kfree(tpm);
+out:
+	return rc;
 }
 
-static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
+static int tpm_tis_acpi_remove(struct acpi_device *device, int type)
 {
-	return tpm_pm_suspend(&dev->dev, msg);
+	struct tpm_chip *chip = dev_get_drvdata(&device->dev);
+	tpm_remove_hardware(&device->dev);
+	iowrite32(~TPM_GLOBAL_INT_ENABLE & ioread32(chip->vendor.iobase +
+				TPM_INT_ENABLE(chip->vendor.locality)),
+		  chip->vendor.iobase +
+		  TPM_INT_ENABLE(chip->vendor.locality));
+	release_locality(chip, chip->vendor.locality, 1);
+	if (chip->vendor.irq)
+		free_irq(chip->vendor.irq, chip);
+	iounmap(chip->vendor.iobase);
+	kfree(device->driver_data);
+	return 0;
 }
 
-static int tpm_tis_pnp_resume(struct pnp_dev *dev)
+static int tpm_tis_acpi_suspend(struct acpi_device *dev, pm_message_t state)
+{
+	return tpm_pm_suspend(&dev->dev, state);
+}
+
+static int tpm_tis_acpi_resume(struct acpi_device *dev)
 {
 	return tpm_pm_resume(&dev->dev);
 }
 
-static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
+static struct acpi_device_id tpm_tis_acpi_tbl[] __devinitdata = {
 	{"PNP0C31", 0},		/* TPM */
 	{"ATM1200", 0},		/* Atmel */
 	{"IFX0102", 0},		/* Infineon */
@@ -625,34 +715,27 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
 	{"BCM0102", 0},		/* Broadcom */
 	{"NSC1200", 0},		/* National */
 	{"ICO0102", 0},		/* Intel */
+	{"INTC0102", 0},	/* TPM spec says to look for this in _CID */
 	/* Add new here */
 	{"", 0},		/* User Specified */
 	{"", 0}			/* Terminator */
 };
-MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
-
-static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
-{
-	struct tpm_chip *chip = pnp_get_drvdata(dev);
-
-	tpm_dev_vendor_release(chip);
-
-	kfree(chip);
-}
-
+MODULE_DEVICE_TABLE(acpi, tpm_tis_acpi_tbl);
 
-static struct pnp_driver tis_pnp_driver = {
+static struct acpi_driver tis_acpi_driver = {
 	.name = "tpm_tis",
-	.id_table = tpm_pnp_tbl,
-	.probe = tpm_tis_pnp_init,
-	.suspend = tpm_tis_pnp_suspend,
-	.resume = tpm_tis_pnp_resume,
-	.remove = tpm_tis_pnp_remove,
+	.ids = tpm_tis_acpi_tbl,
+	.ops = {
+		.add = tpm_tis_acpi_add,
+		.remove = tpm_tis_acpi_remove,
+		.suspend = tpm_tis_acpi_suspend,
+		.resume = tpm_tis_acpi_resume,
+	},
 };
 
-#define TIS_HID_USR_IDX (ARRAY_SIZE(tpm_pnp_tbl) - 2)
-module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
-		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
+#define TIS_HID_USR_IDX (ARRAY_SIZE(tpm_tis_acpi_tbl) - 2)
+module_param_string(hid, tpm_tis_acpi_tbl[TIS_HID_USR_IDX].id,
+		    sizeof(tpm_tis_acpi_tbl[TIS_HID_USR_IDX].id), 0444);
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 
 static struct device_driver tis_drv = {
@@ -685,7 +768,7 @@ static int __init init_tis(void)
 		return rc;
 	}
 
-	return pnp_register_driver(&tis_pnp_driver);
+	return acpi_bus_register_driver(&tis_acpi_driver);
 }
 
 static void __exit cleanup_tis(void)
@@ -714,7 +797,7 @@ static void __exit cleanup_tis(void)
 		platform_device_unregister(pdev);
 		driver_unregister(&tis_drv);
 	} else
-		pnp_unregister_driver(&tis_pnp_driver);
+		acpi_bus_unregister_driver(&tis_acpi_driver);
 }
 
 module_init(init_tis);
-- 
1.6.3.1


  parent reply	other threads:[~2009-07-01  1:23 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-01  1:04 [PATCH 0/6] tpm_tis: various cleanups, and support for Intel iTPM Andy Isaacson
2009-07-01  1:04 ` [PATCH 1/6] tpm_tis: various cleanups Andy Isaacson
2009-09-10 19:56   ` Rajiv Andrade
2009-07-01  1:04 ` [PATCH 2/6] tpm_tis: add MODULE_DEVICE_TABLE to enable autoload Andy Isaacson
2009-09-10 19:56   ` Rajiv Andrade
2009-07-01  1:04 ` [PATCH 3/6] tpm_tis: set timeouts before calling request_locality Andy Isaacson
2009-07-01  1:04 ` [PATCH 4/6] tpm_tis: print complete vendor information Andy Isaacson
2009-09-10 19:57   ` Rajiv Andrade
2009-07-01  1:04 ` Andy Isaacson [this message]
2009-07-01 10:01   ` [PATCH 5/6] tpm_tis: convert from pnp_driver to acpi_driver Alan Cox
2009-07-01 13:45     ` Rajiv Andrade
2009-07-16 17:26       ` Rajiv Andrade
2009-07-16 17:43         ` [PATCH] TPM: DATA_EXPECT bit check bypass Rajiv Andrade
2009-07-16 20:08           ` Valdis.Kletnieks
2009-07-16 20:50             ` Rajiv Andrade
2009-07-16 21:20             ` Rajiv Andrade
2009-07-20 23:28               ` Andy Isaacson
2009-07-24 17:12                 ` Rajiv Andrade
2009-07-20 18:27       ` [PATCH 5/6] tpm_tis: convert from pnp_driver to acpi_driver Andy Isaacson
2009-09-10 19:08         ` Rajiv Andrade
2009-09-10 19:54           ` [PATCH] tpm_tis: TPM_STS_DATA_EXPECT workaround Rajiv Andrade
2009-09-10 19:58             ` Daniel Walker
2009-09-10 20:06               ` Rajiv Andrade
2009-09-10 20:09               ` Rajiv Andrade
2009-09-11 23:34                 ` Seiji Munetoh
2009-09-24 18:43                   ` Rajiv Andrade
2009-10-28  2:45                     ` David Smith
2009-10-31 14:24                       ` Eric Paris
2009-11-01 22:09                         ` James Morris
2009-09-10 20:27               ` Andy Isaacson
2009-07-01  1:04 ` [PATCH 6/6] tpm_tis: add workarounds for iTPM Andy Isaacson
2009-07-03 18:18   ` [tpmdd-devel] " Marcin Obara
2009-07-03 19:33     ` Andy Isaacson
2009-07-03 20:10       ` Marcin Obara
2009-07-03 20:20         ` Andy Isaacson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1246410255-6839-6-git-send-email-adi@vmware.com \
    --to=adi@vmware.com \
    --cc=adi@hexapodia.org \
    --cc=dds@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=seiji.munetoh@gmail.com \
    --cc=shaz.linux@gmail.com \
    --cc=srajiv@linux.vnet.ibm.com \
    --cc=tpmdd-devel@lists.sourceforge.net \
    --cc=zohar@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.