diff mbox

[v2,1/2] tpm, tpm_tis: use acpi_driver instead of pnp_driver

Message ID 1443550232-23294-2-git-send-email-jarkko.sakkinen@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jarkko Sakkinen Sept. 29, 2015, 6:10 p.m. UTC
Migrate to struct acpi_driver in order to get out of 7 character
limitation for the HID.

Reported-by: Matthew Garrett <mjg59@srcf.ucam.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm_tis.c | 124 ++++++++++++++++++++++++++-------------------
 1 file changed, 73 insertions(+), 51 deletions(-)
diff mbox

Patch

diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index f2dffa7..87581b2 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -1,6 +1,6 @@ 
 /*
  * Copyright (C) 2005, 2006 IBM Corporation
- * Copyright (C) 2014 Intel Corporation
+ * Copyright (C) 2014, 2015 Intel Corporation
  *
  * Authors:
  * Leendert van Doorn <leendert@watson.ibm.com>
@@ -22,7 +22,6 @@ 
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/pnp.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
@@ -65,6 +64,17 @@  enum tis_defaults {
 	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
 };
 
+struct tpm_info {
+	unsigned long start;
+	unsigned long len;
+	unsigned int irq;
+};
+
+static struct tpm_info tis_default_info = {
+	.start = TIS_MEM_BASE,
+	.len = TIS_MEM_LEN,
+	.irq = 0,
+};
 
 /* Some timeout values are needed before it is known whether the chip is
  * TPM 1.0 or TPM 2.0.
@@ -90,24 +100,19 @@  struct priv_data {
 	bool irq_tested;
 };
 
-#if defined(CONFIG_PNP) && defined(CONFIG_ACPI)
-static int is_itpm(struct pnp_dev *dev)
+#if defined(CONFIG_ACPI)
+static int is_itpm(struct acpi_device *dev)
 {
-	struct acpi_device *acpi = pnp_acpi_device(dev);
 	struct acpi_hardware_id *id;
 
-	if (!acpi)
-		return 0;
-
-	list_for_each_entry(id, &acpi->pnp.ids, list) {
+	list_for_each_entry(id, &dev->pnp.ids, list)
 		if (!strcmp("INTC0102", id->id))
 			return 1;
-	}
 
 	return 0;
 }
 #else
-static inline int is_itpm(struct pnp_dev *dev)
+static inline int is_itpm(struct acpi_device *dev)
 {
 	return 0;
 }
@@ -600,9 +605,8 @@  static void tpm_tis_remove(struct tpm_chip *chip)
 	release_locality(chip, chip->vendor.locality, 1);
 }
 
-static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
-			resource_size_t start, resource_size_t len,
-			unsigned int irq)
+static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
+			acpi_handle acpi_dev_handle)
 {
 	u32 vendor, intfcaps, intmask;
 	int rc, i, irq_s, irq_e, probe;
@@ -622,7 +626,7 @@  static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
 	chip->acpi_dev_handle = acpi_dev_handle;
 #endif
 
-	chip->vendor.iobase = devm_ioremap(dev, start, len);
+	chip->vendor.iobase = devm_ioremap(dev, tpm_info->start, tpm_info->len);
 	if (!chip->vendor.iobase)
 		return -EIO;
 
@@ -707,7 +711,7 @@  static int tpm_tis_init(struct device *dev, acpi_handle acpi_dev_handle,
 		  chip->vendor.iobase +
 		  TPM_INT_ENABLE(chip->vendor.locality));
 	if (interrupts)
-		chip->vendor.irq = irq;
+		chip->vendor.irq = tpm_info->irq;
 	if (interrupts && !chip->vendor.irq) {
 		irq_s =
 		    ioread8(chip->vendor.iobase +
@@ -886,34 +890,46 @@  static int tpm_tis_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
 
-#ifdef CONFIG_PNP
-static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
-				      const struct pnp_device_id *pnp_id)
+#ifdef CONFIG_ACPI
+static int tpm_check_resource(struct acpi_resource *ares, void *data)
+{
+	struct tpm_info *tpm_info = (struct tpm_info *) data;
+	struct resource res;
+
+	if (acpi_dev_resource_interrupt(ares, 0, &res)) {
+		tpm_info->irq = res.start;
+	} else if (acpi_dev_resource_memory(ares, &res)) {
+		tpm_info->start = res.start;
+		tpm_info->len = resource_size(&res);
+	}
+
+	return 1;
+}
+
+static int tpm_tis_acpi_init(struct acpi_device *acpi_dev)
 {
-	resource_size_t start, len;
-	unsigned int irq = 0;
-	acpi_handle acpi_dev_handle = NULL;
+	struct list_head resources;
+	struct tpm_info tpm_info = tis_default_info;
+	int ret;
+
+	INIT_LIST_HEAD(&resources);
+	ret = acpi_dev_get_resources(acpi_dev, &resources, tpm_check_resource,
+				     &tpm_info);
+	if (ret < 0)
+		return ret;
 
-	start = pnp_mem_start(pnp_dev, 0);
-	len = pnp_mem_len(pnp_dev, 0);
+	acpi_dev_free_resource_list(&resources);
 
-	if (pnp_irq_valid(pnp_dev, 0))
-		irq = pnp_irq(pnp_dev, 0);
-	else
+	if (!tpm_info.irq)
 		interrupts = false;
 
-	if (is_itpm(pnp_dev))
+	if (is_itpm(acpi_dev))
 		itpm = true;
 
-#ifdef CONFIG_ACPI
-	if (pnp_acpi_device(pnp_dev))
-		acpi_dev_handle = pnp_acpi_device(pnp_dev)->handle;
-#endif
-
-	return tpm_tis_init(&pnp_dev->dev, acpi_dev_handle, start, len, irq);
+	return tpm_tis_init(&acpi_dev->dev, &tpm_info, acpi_dev->handle);
 }
 
-static struct pnp_device_id tpm_pnp_tbl[] = {
+static struct acpi_device_id tpm_acpi_tbl[] = {
 	{"PNP0C31", 0},		/* TPM */
 	{"ATM1200", 0},		/* Atmel */
 	{"IFX0102", 0},		/* Infineon */
@@ -925,28 +941,34 @@  static struct pnp_device_id tpm_pnp_tbl[] = {
 	{"", 0},		/* User Specified */
 	{"", 0}			/* Terminator */
 };
-MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+MODULE_DEVICE_TABLE(acpi, tpm_acpi_tbl);
 
-static void tpm_tis_pnp_remove(struct pnp_dev *dev)
+static int tpm_tis_acpi_remove(struct acpi_device *dev)
 {
-	struct tpm_chip *chip = pnp_get_drvdata(dev);
+	struct tpm_chip *chip = dev_get_drvdata(&dev->dev);
+
 	tpm_chip_unregister(chip);
 	tpm_tis_remove(chip);
+
+	return 0;
 }
 
-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,
-	.remove = tpm_tis_pnp_remove,
-	.driver	= {
+	.ids = tpm_acpi_tbl,
+	.ops = {
+		.add = tpm_tis_acpi_init,
+		.remove = tpm_tis_acpi_remove,
+	},
+	.drv = {
 		.pm = &tpm_tis_pm,
 	},
 };
 
-#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -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 \
+	(sizeof(tpm_acpi_tbl) / sizeof(struct acpi_device_id) - 2)
+module_param_string(hid, tpm_acpi_tbl[TIS_HID_USR_IDX].id,
+		    sizeof(tpm_acpi_tbl[TIS_HID_USR_IDX].id), 0444);
 MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
 #endif
 
@@ -965,9 +987,9 @@  MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
 static int __init init_tis(void)
 {
 	int rc;
-#ifdef CONFIG_PNP
+#ifdef CONFIG_ACPI
 	if (!force)
-		return pnp_register_driver(&tis_pnp_driver);
+		return acpi_bus_register_driver(&tis_acpi_driver);
 #endif
 
 	rc = platform_driver_register(&tis_drv);
@@ -978,7 +1000,7 @@  static int __init init_tis(void)
 		rc = PTR_ERR(pdev);
 		goto err_dev;
 	}
-	rc = tpm_tis_init(&pdev->dev, NULL, TIS_MEM_BASE, TIS_MEM_LEN, 0);
+	rc = tpm_tis_init(&pdev->dev, &tis_default_info, NULL);
 	if (rc)
 		goto err_init;
 	return 0;
@@ -992,9 +1014,9 @@  err_dev:
 static void __exit cleanup_tis(void)
 {
 	struct tpm_chip *chip;
-#ifdef CONFIG_PNP
+#ifdef CONFIG_ACPI
 	if (!force) {
-		pnp_unregister_driver(&tis_pnp_driver);
+		acpi_bus_unregister_driver(&tis_acpi_driver);
 		return;
 	}
 #endif