ia64/xen-unstable

changeset 10579:e3ad9b9c95ee

[TPM] Add an upgrade patch to bring TPM subsystem to 2.6.17-rc4.

This patch adds the updated and newer driver plugins appearing in
2.6.17-rc4 to the 2.6.16.13 kernel. The patch needs to be placed into
the patches/linux-2.6.16.13 directory and should be removed once an
upgrade is done to 2.6.17-rc4 or later version.

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Jun 28 16:21:30 2006 +0100 (2006-06-28)
parents da8da6e1e1d6
children d85488fd2196
files patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/patches/linux-2.6.16.13/tpm_plugin_2.6.17.patch	Wed Jun 28 16:21:30 2006 +0100
     1.3 @@ -0,0 +1,1546 @@
     1.4 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c ./drivers/char/tpm/tpm_atmel.c
     1.5 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.c	2006-06-26 18:05:03.000000000 -0400
     1.6 ++++ ./drivers/char/tpm/tpm_atmel.c	2006-06-26 18:16:33.000000000 -0400
     1.7 +@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
     1.8 + 		return -EIO;
     1.9 + 
    1.10 + 	for (i = 0; i < 6; i++) {
    1.11 +-		status = ioread8(chip->vendor->iobase + 1);
    1.12 ++		status = ioread8(chip->vendor.iobase + 1);
    1.13 + 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
    1.14 + 			dev_err(chip->dev, "error reading header\n");
    1.15 + 			return -EIO;
    1.16 + 		}
    1.17 +-		*buf++ = ioread8(chip->vendor->iobase);
    1.18 ++		*buf++ = ioread8(chip->vendor.iobase);
    1.19 + 	}
    1.20 + 
    1.21 + 	/* size of the data received */
    1.22 +@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
    1.23 + 		dev_err(chip->dev,
    1.24 + 			"Recv size(%d) less than available space\n", size);
    1.25 + 		for (; i < size; i++) {	/* clear the waiting data anyway */
    1.26 +-			status = ioread8(chip->vendor->iobase + 1);
    1.27 ++			status = ioread8(chip->vendor.iobase + 1);
    1.28 + 			if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
    1.29 + 				dev_err(chip->dev, "error reading data\n");
    1.30 + 				return -EIO;
    1.31 +@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
    1.32 + 
    1.33 + 	/* read all the data available */
    1.34 + 	for (; i < size; i++) {
    1.35 +-		status = ioread8(chip->vendor->iobase + 1);
    1.36 ++		status = ioread8(chip->vendor.iobase + 1);
    1.37 + 		if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
    1.38 + 			dev_err(chip->dev, "error reading data\n");
    1.39 + 			return -EIO;
    1.40 + 		}
    1.41 +-		*buf++ = ioread8(chip->vendor->iobase);
    1.42 ++		*buf++ = ioread8(chip->vendor.iobase);
    1.43 + 	}
    1.44 + 
    1.45 + 	/* make sure data available is gone */
    1.46 +-	status = ioread8(chip->vendor->iobase + 1);
    1.47 ++	status = ioread8(chip->vendor.iobase + 1);
    1.48 + 
    1.49 + 	if (status & ATML_STATUS_DATA_AVAIL) {
    1.50 + 		dev_err(chip->dev, "data available is stuck\n");
    1.51 +@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
    1.52 + 	dev_dbg(chip->dev, "tpm_atml_send:\n");
    1.53 + 	for (i = 0; i < count; i++) {
    1.54 + 		dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
    1.55 +- 		iowrite8(buf[i], chip->vendor->iobase);
    1.56 ++ 		iowrite8(buf[i], chip->vendor.iobase);
    1.57 + 	}
    1.58 + 
    1.59 + 	return count;
    1.60 +@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
    1.61 + 
    1.62 + static void tpm_atml_cancel(struct tpm_chip *chip)
    1.63 + {
    1.64 +-	iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
    1.65 ++	iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
    1.66 + }
    1.67 + 
    1.68 + static u8 tpm_atml_status(struct tpm_chip *chip)
    1.69 + {
    1.70 +-	return ioread8(chip->vendor->iobase + 1);
    1.71 ++	return ioread8(chip->vendor.iobase + 1);
    1.72 + }
    1.73 + 
    1.74 + static struct file_operations atmel_ops = {
    1.75 +@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
    1.76 + 
    1.77 + static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
    1.78 + 
    1.79 +-static struct tpm_vendor_specific tpm_atmel = {
    1.80 ++static const struct tpm_vendor_specific tpm_atmel = {
    1.81 + 	.recv = tpm_atml_recv,
    1.82 + 	.send = tpm_atml_send,
    1.83 + 	.cancel = tpm_atml_cancel,
    1.84 +@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
    1.85 + 	struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
    1.86 + 
    1.87 + 	if (chip) {
    1.88 +-		if (chip->vendor->have_region)
    1.89 +-			atmel_release_region(chip->vendor->base,
    1.90 +-					     chip->vendor->region_size);
    1.91 +-		atmel_put_base_addr(chip->vendor);
    1.92 ++		if (chip->vendor.have_region)
    1.93 ++			atmel_release_region(chip->vendor.base,
    1.94 ++					     chip->vendor.region_size);
    1.95 ++		atmel_put_base_addr(chip->vendor.iobase);
    1.96 + 		tpm_remove_hardware(chip->dev);
    1.97 + 		platform_device_unregister(pdev);
    1.98 + 	}
    1.99 +@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
   1.100 + static int __init init_atmel(void)
   1.101 + {
   1.102 + 	int rc = 0;
   1.103 ++	void __iomem *iobase = NULL;
   1.104 ++	int have_region, region_size;
   1.105 ++	unsigned long base;
   1.106 ++	struct  tpm_chip *chip;
   1.107 + 
   1.108 + 	driver_register(&atml_drv);
   1.109 + 
   1.110 +-	if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
   1.111 ++	if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
   1.112 + 		rc = -ENODEV;
   1.113 + 		goto err_unreg_drv;
   1.114 + 	}
   1.115 + 
   1.116 +-	tpm_atmel.have_region =
   1.117 ++	have_region =
   1.118 + 	    (atmel_request_region
   1.119 +-	     (tpm_atmel.base, tpm_atmel.region_size,
   1.120 +-	      "tpm_atmel0") == NULL) ? 0 : 1;
   1.121 ++	     (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
   1.122 ++
   1.123 + 
   1.124 + 	if (IS_ERR
   1.125 + 	    (pdev =
   1.126 +@@ -199,17 +203,25 @@ static int __init init_atmel(void)
   1.127 + 		goto err_rel_reg;
   1.128 + 	}
   1.129 + 
   1.130 +-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
   1.131 ++	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
   1.132 ++		rc = -ENODEV;
   1.133 + 		goto err_unreg_dev;
   1.134 ++	}
   1.135 ++
   1.136 ++	chip->vendor.iobase = iobase;
   1.137 ++	chip->vendor.base = base;
   1.138 ++	chip->vendor.have_region = have_region;
   1.139 ++	chip->vendor.region_size = region_size;
   1.140 ++
   1.141 + 	return 0;
   1.142 + 
   1.143 + err_unreg_dev:
   1.144 + 	platform_device_unregister(pdev);
   1.145 + err_rel_reg:
   1.146 +-	atmel_put_base_addr(&tpm_atmel);
   1.147 +-	if (tpm_atmel.have_region)
   1.148 +-		atmel_release_region(tpm_atmel.base,
   1.149 +-				     tpm_atmel.region_size);
   1.150 ++	atmel_put_base_addr(iobase);
   1.151 ++	if (have_region)
   1.152 ++		atmel_release_region(base,
   1.153 ++				     region_size);
   1.154 + err_unreg_drv:
   1.155 + 	driver_unregister(&atml_drv);
   1.156 + 	return rc;
   1.157 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h ./drivers/char/tpm/tpm_atmel.h
   1.158 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_atmel.h	2006-06-26 18:05:03.000000000 -0400
   1.159 ++++ ./drivers/char/tpm/tpm_atmel.h	2006-06-26 18:16:33.000000000 -0400
   1.160 +@@ -28,13 +28,12 @@
   1.161 + #define atmel_request_region request_mem_region
   1.162 + #define atmel_release_region release_mem_region
   1.163 + 
   1.164 +-static inline void atmel_put_base_addr(struct tpm_vendor_specific
   1.165 +-					 *vendor)
   1.166 ++static inline void atmel_put_base_addr(void __iomem *iobase)
   1.167 + {
   1.168 +-	iounmap(vendor->iobase);
   1.169 ++	iounmap(iobase);
   1.170 + }
   1.171 + 
   1.172 +-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
   1.173 ++static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
   1.174 + {
   1.175 + 	struct device_node *dn;
   1.176 + 	unsigned long address, size;
   1.177 +@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
   1.178 + 	else
   1.179 + 		size = reg[naddrc];
   1.180 + 
   1.181 +-	vendor->base = address;
   1.182 +-	vendor->region_size = size;
   1.183 +-	return ioremap(vendor->base, vendor->region_size);
   1.184 ++	*base = address;
   1.185 ++	*region_size = size;
   1.186 ++	return ioremap(*base, *region_size);
   1.187 + }
   1.188 + #else
   1.189 + #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
   1.190 +@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
   1.191 + 	return 0;
   1.192 + }
   1.193 + 
   1.194 +-static inline void atmel_put_base_addr(struct tpm_vendor_specific
   1.195 +-					 *vendor)
   1.196 ++static inline void atmel_put_base_addr(void __iomem *iobase)
   1.197 + {
   1.198 + }
   1.199 + 
   1.200 + /* Determine where to talk to device */
   1.201 +-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
   1.202 +-					 *vendor)
   1.203 ++static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
   1.204 + {
   1.205 + 	int lo, hi;
   1.206 + 
   1.207 +@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
   1.208 + 	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
   1.209 + 	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
   1.210 + 
   1.211 +-	vendor->base = (hi << 8) | lo;
   1.212 +-	vendor->region_size = 2;
   1.213 ++	*base = (hi << 8) | lo;
   1.214 ++	*region_size = 2;
   1.215 + 
   1.216 +-	return ioport_map(vendor->base, vendor->region_size);
   1.217 ++	return ioport_map(*base, *region_size);
   1.218 + }
   1.219 + #endif
   1.220 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c ./drivers/char/tpm/tpm_bios.c
   1.221 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_bios.c	2006-06-26 18:05:03.000000000 -0400
   1.222 ++++ ./drivers/char/tpm/tpm_bios.c	2006-06-26 18:16:33.000000000 -0400
   1.223 +@@ -29,6 +29,11 @@
   1.224 + #define MAX_TEXT_EVENT		1000	/* Max event string length */
   1.225 + #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
   1.226 + 
   1.227 ++enum bios_platform_class {
   1.228 ++	BIOS_CLIENT = 0x00,
   1.229 ++	BIOS_SERVER = 0x01,
   1.230 ++};
   1.231 ++
   1.232 + struct tpm_bios_log {
   1.233 + 	void *bios_event_log;
   1.234 + 	void *bios_event_log_end;
   1.235 +@@ -36,9 +41,18 @@ struct tpm_bios_log {
   1.236 + 
   1.237 + struct acpi_tcpa {
   1.238 + 	struct acpi_table_header hdr;
   1.239 +-	u16 reserved;
   1.240 +-	u32 log_max_len __attribute__ ((packed));
   1.241 +-	u32 log_start_addr __attribute__ ((packed));
   1.242 ++	u16 platform_class;
   1.243 ++	union {
   1.244 ++		struct client_hdr {
   1.245 ++			u32 log_max_len __attribute__ ((packed));
   1.246 ++			u64 log_start_addr __attribute__ ((packed));
   1.247 ++		} client;
   1.248 ++		struct server_hdr {
   1.249 ++			u16 reserved;
   1.250 ++			u64 log_max_len __attribute__ ((packed));
   1.251 ++			u64 log_start_addr __attribute__ ((packed));
   1.252 ++		} server;
   1.253 ++	};
   1.254 + };
   1.255 + 
   1.256 + struct tcpa_event {
   1.257 +@@ -91,6 +105,12 @@ static const char* tcpa_event_type_strin
   1.258 + 	"Non-Host Info"
   1.259 + };
   1.260 + 
   1.261 ++struct tcpa_pc_event {
   1.262 ++	u32 event_id;
   1.263 ++	u32 event_size;
   1.264 ++	u8 event_data[0];
   1.265 ++};
   1.266 ++
   1.267 + enum tcpa_pc_event_ids {
   1.268 + 	SMBIOS = 1,
   1.269 + 	BIS_CERT,
   1.270 +@@ -100,14 +120,15 @@ enum tcpa_pc_event_ids {
   1.271 + 	NVRAM,
   1.272 + 	OPTION_ROM_EXEC,
   1.273 + 	OPTION_ROM_CONFIG,
   1.274 +-	OPTION_ROM_MICROCODE,
   1.275 ++	OPTION_ROM_MICROCODE = 10,
   1.276 + 	S_CRTM_VERSION,
   1.277 + 	S_CRTM_CONTENTS,
   1.278 + 	POST_CONTENTS,
   1.279 ++	HOST_TABLE_OF_DEVICES,
   1.280 + };
   1.281 + 
   1.282 + static const char* tcpa_pc_event_id_strings[] = {
   1.283 +-	""
   1.284 ++	"",
   1.285 + 	"SMBIOS",
   1.286 + 	"BIS Certificate",
   1.287 + 	"POST BIOS ",
   1.288 +@@ -116,10 +137,12 @@ static const char* tcpa_pc_event_id_stri
   1.289 + 	"NVRAM",
   1.290 + 	"Option ROM",
   1.291 + 	"Option ROM config",
   1.292 +-	"Option ROM microcode",
   1.293 ++	"",
   1.294 ++	"Option ROM microcode ",
   1.295 + 	"S-CRTM Version",
   1.296 +-	"S-CRTM Contents",
   1.297 +-	"S-CRTM POST Contents",
   1.298 ++	"S-CRTM Contents ",
   1.299 ++	"POST Contents ",
   1.300 ++	"Table of Devices",
   1.301 + };
   1.302 + 
   1.303 + /* returns pointer to start of pos. entry of tcg log */
   1.304 +@@ -191,7 +214,7 @@ static int get_event_name(char *dest, st
   1.305 + 	const char *name = "";
   1.306 + 	char data[40] = "";
   1.307 + 	int i, n_len = 0, d_len = 0;
   1.308 +-	u32 event_id;
   1.309 ++	struct tcpa_pc_event *pc_event;
   1.310 + 
   1.311 + 	switch(event->event_type) {
   1.312 + 	case PREBOOT:
   1.313 +@@ -220,31 +243,32 @@ static int get_event_name(char *dest, st
   1.314 + 		}
   1.315 + 		break;
   1.316 + 	case EVENT_TAG:
   1.317 +-		event_id = be32_to_cpu(*((u32 *)event_entry));
   1.318 ++		pc_event = (struct tcpa_pc_event *)event_entry;
   1.319 + 
   1.320 + 		/* ToDo Row data -> Base64 */
   1.321 + 
   1.322 +-		switch (event_id) {
   1.323 ++		switch (pc_event->event_id) {
   1.324 + 		case SMBIOS:
   1.325 + 		case BIS_CERT:
   1.326 + 		case CMOS:
   1.327 + 		case NVRAM:
   1.328 + 		case OPTION_ROM_EXEC:
   1.329 + 		case OPTION_ROM_CONFIG:
   1.330 +-		case OPTION_ROM_MICROCODE:
   1.331 + 		case S_CRTM_VERSION:
   1.332 +-		case S_CRTM_CONTENTS:
   1.333 +-		case POST_CONTENTS:
   1.334 +-			name = tcpa_pc_event_id_strings[event_id];
   1.335 ++			name = tcpa_pc_event_id_strings[pc_event->event_id];
   1.336 + 			n_len = strlen(name);
   1.337 + 			break;
   1.338 ++		/* hash data */
   1.339 + 		case POST_BIOS_ROM:
   1.340 + 		case ESCD:
   1.341 +-			name = tcpa_pc_event_id_strings[event_id];
   1.342 ++		case OPTION_ROM_MICROCODE:
   1.343 ++		case S_CRTM_CONTENTS:
   1.344 ++		case POST_CONTENTS:
   1.345 ++			name = tcpa_pc_event_id_strings[pc_event->event_id];
   1.346 + 			n_len = strlen(name);
   1.347 + 			for (i = 0; i < 20; i++)
   1.348 +-				d_len += sprintf(data, "%02x",
   1.349 +-						event_entry[8 + i]);
   1.350 ++				d_len += sprintf(&data[2*i], "%02x",
   1.351 ++						pc_event->event_data[i]);
   1.352 + 			break;
   1.353 + 		default:
   1.354 + 			break;
   1.355 +@@ -260,52 +284,13 @@ static int get_event_name(char *dest, st
   1.356 + 
   1.357 + static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
   1.358 + {
   1.359 ++	struct tcpa_event *event = v;
   1.360 ++	char *data = v;
   1.361 ++	int i;
   1.362 + 
   1.363 +-	char *eventname;
   1.364 +-	char data[4];
   1.365 +-	u32 help;
   1.366 +-	int i, len;
   1.367 +-	struct tcpa_event *event = (struct tcpa_event *) v;
   1.368 +-	unsigned char *event_entry =
   1.369 +-	    (unsigned char *) (v + sizeof(struct tcpa_event));
   1.370 +-
   1.371 +-	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
   1.372 +-	if (!eventname) {
   1.373 +-		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
   1.374 +-		       __func__);
   1.375 +-		return -ENOMEM;
   1.376 +-	}
   1.377 +-
   1.378 +-	/* 1st: PCR used is in little-endian format (4 bytes) */
   1.379 +-	help = le32_to_cpu(event->pcr_index);
   1.380 +-	memcpy(data, &help, 4);
   1.381 +-	for (i = 0; i < 4; i++)
   1.382 +-		seq_putc(m, data[i]);
   1.383 +-
   1.384 +-	/* 2nd: SHA1 (20 bytes) */
   1.385 +-	for (i = 0; i < 20; i++)
   1.386 +-		seq_putc(m, event->pcr_value[i]);
   1.387 +-
   1.388 +-	/* 3rd: event type identifier (4 bytes) */
   1.389 +-	help = le32_to_cpu(event->event_type);
   1.390 +-	memcpy(data, &help, 4);
   1.391 +-	for (i = 0; i < 4; i++)
   1.392 ++	for (i = 0; i < sizeof(struct tcpa_event) + event->event_size; i++)
   1.393 + 		seq_putc(m, data[i]);
   1.394 + 
   1.395 +-	len = 0;
   1.396 +-
   1.397 +-	len += get_event_name(eventname, event, event_entry);
   1.398 +-
   1.399 +-	/* 4th:  filename <= 255 + \'0' delimiter */
   1.400 +-	if (len > TCG_EVENT_NAME_LEN_MAX)
   1.401 +-		len = TCG_EVENT_NAME_LEN_MAX;
   1.402 +-
   1.403 +-	for (i = 0; i < len; i++)
   1.404 +-		seq_putc(m, eventname[i]);
   1.405 +-
   1.406 +-	/* 5th: delimiter */
   1.407 +-	seq_putc(m, '\0');
   1.408 +-
   1.409 + 	return 0;
   1.410 + }
   1.411 + 
   1.412 +@@ -353,6 +338,7 @@ static int tpm_ascii_bios_measurements_s
   1.413 + 	/* 4th: eventname <= max + \'0' delimiter */
   1.414 + 	seq_printf(m, " %s\n", eventname);
   1.415 + 
   1.416 ++	kfree(eventname);
   1.417 + 	return 0;
   1.418 + }
   1.419 + 
   1.420 +@@ -376,6 +362,7 @@ static int read_log(struct tpm_bios_log 
   1.421 + 	struct acpi_tcpa *buff;
   1.422 + 	acpi_status status;
   1.423 + 	struct acpi_table_header *virt;
   1.424 ++	u64 len, start;
   1.425 + 
   1.426 + 	if (log->bios_event_log != NULL) {
   1.427 + 		printk(KERN_ERR
   1.428 +@@ -396,27 +383,37 @@ static int read_log(struct tpm_bios_log 
   1.429 + 		return -EIO;
   1.430 + 	}
   1.431 + 
   1.432 +-	if (buff->log_max_len == 0) {
   1.433 ++	switch(buff->platform_class) {
   1.434 ++	case BIOS_SERVER:
   1.435 ++		len = buff->server.log_max_len;
   1.436 ++		start = buff->server.log_start_addr;
   1.437 ++		break;
   1.438 ++	case BIOS_CLIENT:
   1.439 ++	default:
   1.440 ++		len = buff->client.log_max_len;
   1.441 ++		start = buff->client.log_start_addr;
   1.442 ++		break;
   1.443 ++	}
   1.444 ++	if (!len) {
   1.445 + 		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
   1.446 + 		return -EIO;
   1.447 + 	}
   1.448 + 
   1.449 + 	/* malloc EventLog space */
   1.450 +-	log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
   1.451 ++	log->bios_event_log = kmalloc(len, GFP_KERNEL);
   1.452 + 	if (!log->bios_event_log) {
   1.453 +-		printk
   1.454 +-		    ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
   1.455 +-		     __func__);
   1.456 ++		printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
   1.457 ++			__func__);
   1.458 + 		return -ENOMEM;
   1.459 + 	}
   1.460 + 
   1.461 +-	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
   1.462 ++	log->bios_event_log_end = log->bios_event_log + len;
   1.463 + 
   1.464 +-	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
   1.465 ++	acpi_os_map_memory(start, len, (void *) &virt);
   1.466 + 
   1.467 +-	memcpy(log->bios_event_log, virt, buff->log_max_len);
   1.468 ++	memcpy(log->bios_event_log, virt, len);
   1.469 + 
   1.470 +-	acpi_os_unmap_memory(virt, buff->log_max_len);
   1.471 ++	acpi_os_unmap_memory(virt, len);
   1.472 + 	return 0;
   1.473 + }
   1.474 + 
   1.475 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c ./drivers/char/tpm/tpm_infineon.c
   1.476 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_infineon.c	2006-06-26 18:05:03.000000000 -0400
   1.477 ++++ ./drivers/char/tpm/tpm_infineon.c	2006-06-26 18:16:33.000000000 -0400
   1.478 +@@ -15,6 +15,7 @@
   1.479 +  * License.
   1.480 +  */
   1.481 + 
   1.482 ++#include <linux/init.h>
   1.483 + #include <linux/pnp.h>
   1.484 + #include "tpm.h"
   1.485 + 
   1.486 +@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *c
   1.487 + 
   1.488 + 	if (clear_wrfifo) {
   1.489 + 		for (i = 0; i < 4096; i++) {
   1.490 +-			status = inb(chip->vendor->base + WRFIFO);
   1.491 ++			status = inb(chip->vendor.base + WRFIFO);
   1.492 + 			if (status == 0xff) {
   1.493 + 				if (check == 5)
   1.494 + 					break;
   1.495 +@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *c
   1.496 + 	 */
   1.497 + 	i = 0;
   1.498 + 	do {
   1.499 +-		status = inb(chip->vendor->base + RDFIFO);
   1.500 +-		status = inb(chip->vendor->base + STAT);
   1.501 ++		status = inb(chip->vendor.base + RDFIFO);
   1.502 ++		status = inb(chip->vendor.base + STAT);
   1.503 + 		i++;
   1.504 + 		if (i == TPM_MAX_TRIES)
   1.505 + 			return -EIO;
   1.506 +@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, i
   1.507 + 	int status;
   1.508 + 	int i;
   1.509 + 	for (i = 0; i < TPM_MAX_TRIES; i++) {
   1.510 +-		status = inb(chip->vendor->base + STAT);
   1.511 ++		status = inb(chip->vendor.base + STAT);
   1.512 + 		/* check the status-register if wait_for_bit is set */
   1.513 + 		if (status & 1 << wait_for_bit)
   1.514 + 			break;
   1.515 +@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, i
   1.516 + static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
   1.517 + {
   1.518 + 	wait(chip, STAT_XFE);
   1.519 +-	outb(sendbyte, chip->vendor->base + WRFIFO);
   1.520 ++	outb(sendbyte, chip->vendor.base + WRFIFO);
   1.521 + }
   1.522 + 
   1.523 +     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
   1.524 +@@ -204,7 +205,7 @@ recv_begin:
   1.525 + 		ret = wait(chip, STAT_RDA);
   1.526 + 		if (ret)
   1.527 + 			return -EIO;
   1.528 +-		buf[i] = inb(chip->vendor->base + RDFIFO);
   1.529 ++		buf[i] = inb(chip->vendor.base + RDFIFO);
   1.530 + 	}
   1.531 + 
   1.532 + 	if (buf[0] != TPM_VL_VER) {
   1.533 +@@ -219,7 +220,7 @@ recv_begin:
   1.534 + 
   1.535 + 		for (i = 0; i < size; i++) {
   1.536 + 			wait(chip, STAT_RDA);
   1.537 +-			buf[i] = inb(chip->vendor->base + RDFIFO);
   1.538 ++			buf[i] = inb(chip->vendor.base + RDFIFO);
   1.539 + 		}
   1.540 + 
   1.541 + 		if ((size == 0x6D00) && (buf[1] == 0x80)) {
   1.542 +@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip 
   1.543 + 	u8 count_high, count_low, count_4, count_3, count_2, count_1;
   1.544 + 
   1.545 + 	/* Disabling Reset, LP and IRQC */
   1.546 +-	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
   1.547 ++	outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
   1.548 + 
   1.549 + 	ret = empty_fifo(chip, 1);
   1.550 + 	if (ret) {
   1.551 +@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_ch
   1.552 + 
   1.553 + static u8 tpm_inf_status(struct tpm_chip *chip)
   1.554 + {
   1.555 +-	return inb(chip->vendor->base + STAT);
   1.556 ++	return inb(chip->vendor.base + STAT);
   1.557 + }
   1.558 + 
   1.559 + static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
   1.560 +@@ -346,7 +347,7 @@ static struct file_operations inf_ops = 
   1.561 + 	.release = tpm_release,
   1.562 + };
   1.563 + 
   1.564 +-static struct tpm_vendor_specific tpm_inf = {
   1.565 ++static const struct tpm_vendor_specific tpm_inf = {
   1.566 + 	.recv = tpm_inf_recv,
   1.567 + 	.send = tpm_inf_send,
   1.568 + 	.cancel = tpm_inf_cancel,
   1.569 +@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(s
   1.570 + 	int version[2];
   1.571 + 	int productid[2];
   1.572 + 	char chipname[20];
   1.573 ++	struct tpm_chip *chip;
   1.574 + 
   1.575 + 	/* read IO-ports through PnP */
   1.576 + 	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
   1.577 +@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(s
   1.578 + 			goto err_last;
   1.579 + 		}
   1.580 + 		/* publish my base address and request region */
   1.581 +-		tpm_inf.base = TPM_INF_BASE;
   1.582 + 		if (request_region
   1.583 +-		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
   1.584 ++		    (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
   1.585 + 			rc = -EINVAL;
   1.586 + 			goto err_last;
   1.587 + 		}
   1.588 +-		if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
   1.589 +-				"tpm_infineon0") == NULL) {
   1.590 ++		if (request_region
   1.591 ++		    (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
   1.592 + 			rc = -EINVAL;
   1.593 + 			goto err_last;
   1.594 + 		}
   1.595 +@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(s
   1.596 + 
   1.597 + 		/* configure TPM with IO-ports */
   1.598 + 		outb(IOLIMH, TPM_INF_ADDR);
   1.599 +-		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
   1.600 ++		outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
   1.601 + 		outb(IOLIML, TPM_INF_ADDR);
   1.602 +-		outb((tpm_inf.base & 0xff), TPM_INF_DATA);
   1.603 ++		outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
   1.604 + 
   1.605 + 		/* control if IO-ports are set correctly */
   1.606 + 		outb(IOLIMH, TPM_INF_ADDR);
   1.607 +@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(s
   1.608 + 		outb(IOLIML, TPM_INF_ADDR);
   1.609 + 		iol = inb(TPM_INF_DATA);
   1.610 + 
   1.611 +-		if ((ioh << 8 | iol) != tpm_inf.base) {
   1.612 ++		if ((ioh << 8 | iol) != TPM_INF_BASE) {
   1.613 + 			dev_err(&dev->dev,
   1.614 +-				"Could not set IO-ports to 0x%lx\n",
   1.615 +-				tpm_inf.base);
   1.616 ++				"Could not set IO-ports to 0x%x\n",
   1.617 ++				TPM_INF_BASE);
   1.618 + 			rc = -EIO;
   1.619 + 			goto err_release_region;
   1.620 + 		}
   1.621 +@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(s
   1.622 + 		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
   1.623 + 
   1.624 + 		/* disable RESET, LP and IRQC */
   1.625 +-		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
   1.626 ++		outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
   1.627 + 
   1.628 + 		/* Finally, we're done, print some infos */
   1.629 + 		dev_info(&dev->dev, "TPM found: "
   1.630 + 			 "config base 0x%x, "
   1.631 + 			 "io base 0x%x, "
   1.632 +-			 "chip version %02x%02x, "
   1.633 +-			 "vendor id %x%x (Infineon), "
   1.634 +-			 "product id %02x%02x"
   1.635 ++			 "chip version 0x%02x%02x, "
   1.636 ++			 "vendor id 0x%x%x (Infineon), "
   1.637 ++			 "product id 0x%02x%02x"
   1.638 + 			 "%s\n",
   1.639 + 			 TPM_INF_ADDR,
   1.640 + 			 TPM_INF_BASE,
   1.641 +@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(s
   1.642 + 			 vendorid[0], vendorid[1],
   1.643 + 			 productid[0], productid[1], chipname);
   1.644 + 
   1.645 +-		rc = tpm_register_hardware(&dev->dev, &tpm_inf);
   1.646 +-		if (rc < 0) {
   1.647 +-			rc = -ENODEV;
   1.648 ++		if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
   1.649 + 			goto err_release_region;
   1.650 + 		}
   1.651 ++		chip->vendor.base = TPM_INF_BASE;
   1.652 + 		return 0;
   1.653 + 	} else {
   1.654 + 		rc = -ENODEV;
   1.655 +@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(s
   1.656 + 	}
   1.657 + 
   1.658 + err_release_region:
   1.659 +-	release_region(tpm_inf.base, TPM_INF_PORT_LEN);
   1.660 ++	release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
   1.661 + 	release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
   1.662 + 
   1.663 + err_last:
   1.664 +@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove
   1.665 + 	struct tpm_chip *chip = pnp_get_drvdata(dev);
   1.666 + 
   1.667 + 	if (chip) {
   1.668 +-		release_region(chip->vendor->base, TPM_INF_PORT_LEN);
   1.669 ++		release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
   1.670 ++		release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
   1.671 + 		tpm_remove_hardware(chip->dev);
   1.672 + 	}
   1.673 + }
   1.674 +@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
   1.675 + 	},
   1.676 + 	.id_table = tpm_pnp_tbl,
   1.677 + 	.probe = tpm_inf_pnp_probe,
   1.678 +-	.remove = tpm_inf_pnp_remove,
   1.679 ++	.remove = __devexit_p(tpm_inf_pnp_remove),
   1.680 + };
   1.681 + 
   1.682 + static int __init init_inf(void)
   1.683 +@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
   1.684 + 
   1.685 + MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
   1.686 + MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
   1.687 +-MODULE_VERSION("1.7");
   1.688 ++MODULE_VERSION("1.8");
   1.689 + MODULE_LICENSE("GPL");
   1.690 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c ./drivers/char/tpm/tpm_nsc.c
   1.691 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_nsc.c	2006-06-26 18:05:03.000000000 -0400
   1.692 ++++ ./drivers/char/tpm/tpm_nsc.c	2006-06-26 18:16:33.000000000 -0400
   1.693 +@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
   1.694 + 	unsigned long stop;
   1.695 + 
   1.696 + 	/* status immediately available check */
   1.697 +-	*data = inb(chip->vendor->base + NSC_STATUS);
   1.698 ++	*data = inb(chip->vendor.base + NSC_STATUS);
   1.699 + 	if ((*data & mask) == val)
   1.700 + 		return 0;
   1.701 + 
   1.702 +@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
   1.703 + 	stop = jiffies + 10 * HZ;
   1.704 + 	do {
   1.705 + 		msleep(TPM_TIMEOUT);
   1.706 +-		*data = inb(chip->vendor->base + 1);
   1.707 ++		*data = inb(chip->vendor.base + 1);
   1.708 + 		if ((*data & mask) == val)
   1.709 + 			return 0;
   1.710 + 	}
   1.711 +@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
   1.712 + 	unsigned long stop;
   1.713 + 
   1.714 + 	/* status immediately available check */
   1.715 +-	status = inb(chip->vendor->base + NSC_STATUS);
   1.716 ++	status = inb(chip->vendor.base + NSC_STATUS);
   1.717 + 	if (status & NSC_STATUS_OBF)
   1.718 +-		status = inb(chip->vendor->base + NSC_DATA);
   1.719 ++		status = inb(chip->vendor.base + NSC_DATA);
   1.720 + 	if (status & NSC_STATUS_RDY)
   1.721 + 		return 0;
   1.722 + 
   1.723 +@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
   1.724 + 	stop = jiffies + 100;
   1.725 + 	do {
   1.726 + 		msleep(TPM_TIMEOUT);
   1.727 +-		status = inb(chip->vendor->base + NSC_STATUS);
   1.728 ++		status = inb(chip->vendor.base + NSC_STATUS);
   1.729 + 		if (status & NSC_STATUS_OBF)
   1.730 +-			status = inb(chip->vendor->base + NSC_DATA);
   1.731 ++			status = inb(chip->vendor.base + NSC_DATA);
   1.732 + 		if (status & NSC_STATUS_RDY)
   1.733 + 			return 0;
   1.734 + 	}
   1.735 +@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip 
   1.736 + 		return -EIO;
   1.737 + 	}
   1.738 + 	if ((data =
   1.739 +-	     inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
   1.740 ++	     inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
   1.741 + 		dev_err(chip->dev, "not in normal mode (0x%x)\n",
   1.742 + 			data);
   1.743 + 		return -EIO;
   1.744 +@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip 
   1.745 + 		}
   1.746 + 		if (data & NSC_STATUS_F0)
   1.747 + 			break;
   1.748 +-		*p = inb(chip->vendor->base + NSC_DATA);
   1.749 ++		*p = inb(chip->vendor.base + NSC_DATA);
   1.750 + 	}
   1.751 + 
   1.752 + 	if ((data & NSC_STATUS_F0) == 0 &&
   1.753 +@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip 
   1.754 + 		dev_err(chip->dev, "F0 not set\n");
   1.755 + 		return -EIO;
   1.756 + 	}
   1.757 +-	if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
   1.758 ++	if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
   1.759 + 		dev_err(chip->dev,
   1.760 + 			"expected end of command(0x%x)\n", data);
   1.761 + 		return -EIO;
   1.762 +@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip 
   1.763 + 	 * fix it. Not sure why this is needed, we followed the flow
   1.764 + 	 * chart in the manual to the letter.
   1.765 + 	 */
   1.766 +-	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
   1.767 ++	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
   1.768 + 
   1.769 + 	if (nsc_wait_for_ready(chip) != 0)
   1.770 + 		return -EIO;
   1.771 +@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip 
   1.772 + 		return -EIO;
   1.773 + 	}
   1.774 + 
   1.775 +-	outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
   1.776 ++	outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
   1.777 + 	if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
   1.778 + 		dev_err(chip->dev, "IBR timeout\n");
   1.779 + 		return -EIO;
   1.780 +@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip 
   1.781 + 				"IBF timeout (while writing data)\n");
   1.782 + 			return -EIO;
   1.783 + 		}
   1.784 +-		outb(buf[i], chip->vendor->base + NSC_DATA);
   1.785 ++		outb(buf[i], chip->vendor.base + NSC_DATA);
   1.786 + 	}
   1.787 + 
   1.788 + 	if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
   1.789 + 		dev_err(chip->dev, "IBF timeout\n");
   1.790 + 		return -EIO;
   1.791 + 	}
   1.792 +-	outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
   1.793 ++	outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
   1.794 + 
   1.795 + 	return count;
   1.796 + }
   1.797 + 
   1.798 + static void tpm_nsc_cancel(struct tpm_chip *chip)
   1.799 + {
   1.800 +-	outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
   1.801 ++	outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
   1.802 + }
   1.803 + 
   1.804 + static u8 tpm_nsc_status(struct tpm_chip *chip)
   1.805 + {
   1.806 +-	return inb(chip->vendor->base + NSC_STATUS);
   1.807 ++	return inb(chip->vendor.base + NSC_STATUS);
   1.808 + }
   1.809 + 
   1.810 + static struct file_operations nsc_ops = {
   1.811 +@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = 
   1.812 + 
   1.813 + static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
   1.814 + 
   1.815 +-static struct tpm_vendor_specific tpm_nsc = {
   1.816 ++static const struct tpm_vendor_specific tpm_nsc = {
   1.817 + 	.recv = tpm_nsc_recv,
   1.818 + 	.send = tpm_nsc_send,
   1.819 + 	.cancel = tpm_nsc_cancel,
   1.820 +@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
   1.821 + {
   1.822 + 	struct tpm_chip *chip = dev_get_drvdata(dev);
   1.823 + 	if ( chip ) {
   1.824 +-		release_region(chip->vendor->base, 2);
   1.825 ++		release_region(chip->vendor.base, 2);
   1.826 + 		tpm_remove_hardware(chip->dev);
   1.827 + 	}
   1.828 + }
   1.829 +@@ -286,7 +286,8 @@ static int __init init_nsc(void)
   1.830 + 	int rc = 0;
   1.831 + 	int lo, hi;
   1.832 + 	int nscAddrBase = TPM_ADDR;
   1.833 +-
   1.834 ++	struct tpm_chip *chip;
   1.835 ++	unsigned long base;
   1.836 + 
   1.837 + 	/* verify that it is a National part (SID) */
   1.838 + 	if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
   1.839 +@@ -300,7 +301,7 @@ static int __init init_nsc(void)
   1.840 + 
   1.841 + 	hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
   1.842 + 	lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
   1.843 +-	tpm_nsc.base = (hi<<8) | lo;
   1.844 ++	base = (hi<<8) | lo;
   1.845 + 
   1.846 + 	/* enable the DPM module */
   1.847 + 	tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
   1.848 +@@ -320,13 +321,15 @@ static int __init init_nsc(void)
   1.849 + 	if ((rc = platform_device_register(pdev)) < 0)
   1.850 + 		goto err_free_dev;
   1.851 + 
   1.852 +-	if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
   1.853 ++	if (request_region(base, 2, "tpm_nsc0") == NULL ) {
   1.854 + 		rc = -EBUSY;
   1.855 + 		goto err_unreg_dev;
   1.856 + 	}
   1.857 + 
   1.858 +-	if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
   1.859 ++	if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
   1.860 ++		rc = -ENODEV;
   1.861 + 		goto err_rel_reg;
   1.862 ++	}
   1.863 + 
   1.864 + 	dev_dbg(&pdev->dev, "NSC TPM detected\n");
   1.865 + 	dev_dbg(&pdev->dev,
   1.866 +@@ -361,10 +364,12 @@ static int __init init_nsc(void)
   1.867 + 		 "NSC TPM revision %d\n",
   1.868 + 		 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
   1.869 + 
   1.870 ++	chip->vendor.base = base;
   1.871 ++
   1.872 + 	return 0;
   1.873 + 
   1.874 + err_rel_reg:
   1.875 +-	release_region(tpm_nsc.base, 2);
   1.876 ++	release_region(base, 2);
   1.877 + err_unreg_dev:
   1.878 + 	platform_device_unregister(pdev);
   1.879 + err_free_dev:
   1.880 +diff -pruN ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c ./drivers/char/tpm/tpm_tis.c
   1.881 +--- ../pristine-linux-2.6.16.13/drivers/char/tpm/tpm_tis.c	1969-12-31 19:00:00.000000000 -0500
   1.882 ++++ ./drivers/char/tpm/tpm_tis.c	2006-06-26 18:16:33.000000000 -0400
   1.883 +@@ -0,0 +1,665 @@
   1.884 ++/*
   1.885 ++ * Copyright (C) 2005, 2006 IBM Corporation
   1.886 ++ *
   1.887 ++ * Authors:
   1.888 ++ * Leendert van Doorn <leendert@watson.ibm.com>
   1.889 ++ * Kylene Hall <kjhall@us.ibm.com>
   1.890 ++ *
   1.891 ++ * Device driver for TCG/TCPA TPM (trusted platform module).
   1.892 ++ * Specifications at www.trustedcomputinggroup.org
   1.893 ++ *
   1.894 ++ * This device driver implements the TPM interface as defined in
   1.895 ++ * the TCG TPM Interface Spec version 1.2, revision 1.0.
   1.896 ++ *
   1.897 ++ * This program is free software; you can redistribute it and/or
   1.898 ++ * modify it under the terms of the GNU General Public License as
   1.899 ++ * published by the Free Software Foundation, version 2 of the
   1.900 ++ * License.
   1.901 ++ */
   1.902 ++#include <linux/init.h>
   1.903 ++#include <linux/module.h>
   1.904 ++#include <linux/moduleparam.h>
   1.905 ++#include <linux/pnp.h>
   1.906 ++#include <linux/interrupt.h>
   1.907 ++#include <linux/wait.h>
   1.908 ++#include "tpm.h"
   1.909 ++
   1.910 ++#define TPM_HEADER_SIZE 10
   1.911 ++
   1.912 ++enum tis_access {
   1.913 ++	TPM_ACCESS_VALID = 0x80,
   1.914 ++	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
   1.915 ++	TPM_ACCESS_REQUEST_PENDING = 0x04,
   1.916 ++	TPM_ACCESS_REQUEST_USE = 0x02,
   1.917 ++};
   1.918 ++
   1.919 ++enum tis_status {
   1.920 ++	TPM_STS_VALID = 0x80,
   1.921 ++	TPM_STS_COMMAND_READY = 0x40,
   1.922 ++	TPM_STS_GO = 0x20,
   1.923 ++	TPM_STS_DATA_AVAIL = 0x10,
   1.924 ++	TPM_STS_DATA_EXPECT = 0x08,
   1.925 ++};
   1.926 ++
   1.927 ++enum tis_int_flags {
   1.928 ++	TPM_GLOBAL_INT_ENABLE = 0x80000000,
   1.929 ++	TPM_INTF_BURST_COUNT_STATIC = 0x100,
   1.930 ++	TPM_INTF_CMD_READY_INT = 0x080,
   1.931 ++	TPM_INTF_INT_EDGE_FALLING = 0x040,
   1.932 ++	TPM_INTF_INT_EDGE_RISING = 0x020,
   1.933 ++	TPM_INTF_INT_LEVEL_LOW = 0x010,
   1.934 ++	TPM_INTF_INT_LEVEL_HIGH = 0x008,
   1.935 ++	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
   1.936 ++	TPM_INTF_STS_VALID_INT = 0x002,
   1.937 ++	TPM_INTF_DATA_AVAIL_INT = 0x001,
   1.938 ++};
   1.939 ++
   1.940 ++enum tis_defaults {
   1.941 ++	TIS_MEM_BASE = 0xFED40000,
   1.942 ++	TIS_MEM_LEN = 0x5000,
   1.943 ++	TIS_SHORT_TIMEOUT = 750,	/* ms */
   1.944 ++	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
   1.945 ++};
   1.946 ++
   1.947 ++#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
   1.948 ++#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
   1.949 ++#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
   1.950 ++#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
   1.951 ++#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
   1.952 ++#define	TPM_STS(l)			(0x0018 | ((l) << 12))
   1.953 ++#define	TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
   1.954 ++
   1.955 ++#define	TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
   1.956 ++#define	TPM_RID(l)			(0x0F04 | ((l) << 12))
   1.957 ++
   1.958 ++static LIST_HEAD(tis_chips);
   1.959 ++static DEFINE_SPINLOCK(tis_lock);
   1.960 ++
   1.961 ++static int check_locality(struct tpm_chip *chip, int l)
   1.962 ++{
   1.963 ++	if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
   1.964 ++	     (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
   1.965 ++	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
   1.966 ++		return chip->vendor.locality = l;
   1.967 ++
   1.968 ++	return -1;
   1.969 ++}
   1.970 ++
   1.971 ++static void release_locality(struct tpm_chip *chip, int l, int force)
   1.972 ++{
   1.973 ++	if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
   1.974 ++		      (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
   1.975 ++	    (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
   1.976 ++		iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
   1.977 ++			 chip->vendor.iobase + TPM_ACCESS(l));
   1.978 ++}
   1.979 ++
   1.980 ++static int request_locality(struct tpm_chip *chip, int l)
   1.981 ++{
   1.982 ++	unsigned long stop;
   1.983 ++	long rc;
   1.984 ++
   1.985 ++	if (check_locality(chip, l) >= 0)
   1.986 ++		return l;
   1.987 ++
   1.988 ++	iowrite8(TPM_ACCESS_REQUEST_USE,
   1.989 ++		 chip->vendor.iobase + TPM_ACCESS(l));
   1.990 ++
   1.991 ++	if (chip->vendor.irq) {
   1.992 ++		rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
   1.993 ++						      (check_locality
   1.994 ++						       (chip, l) >= 0),
   1.995 ++						      chip->vendor.timeout_a);
   1.996 ++		if (rc > 0)
   1.997 ++			return l;
   1.998 ++
   1.999 ++	} else {
  1.1000 ++		/* wait for burstcount */
  1.1001 ++		stop = jiffies + chip->vendor.timeout_a;
  1.1002 ++		do {
  1.1003 ++			if (check_locality(chip, l) >= 0)
  1.1004 ++				return l;
  1.1005 ++			msleep(TPM_TIMEOUT);
  1.1006 ++		}
  1.1007 ++		while (time_before(jiffies, stop));
  1.1008 ++	}
  1.1009 ++	return -1;
  1.1010 ++}
  1.1011 ++
  1.1012 ++static u8 tpm_tis_status(struct tpm_chip *chip)
  1.1013 ++{
  1.1014 ++	return ioread8(chip->vendor.iobase +
  1.1015 ++		       TPM_STS(chip->vendor.locality));
  1.1016 ++}
  1.1017 ++
  1.1018 ++static void tpm_tis_ready(struct tpm_chip *chip)
  1.1019 ++{
  1.1020 ++	/* this causes the current command to be aborted */
  1.1021 ++	iowrite8(TPM_STS_COMMAND_READY,
  1.1022 ++		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
  1.1023 ++}
  1.1024 ++
  1.1025 ++static int get_burstcount(struct tpm_chip *chip)
  1.1026 ++{
  1.1027 ++	unsigned long stop;
  1.1028 ++	int burstcnt;
  1.1029 ++
  1.1030 ++	/* wait for burstcount */
  1.1031 ++	/* which timeout value, spec has 2 answers (c & d) */
  1.1032 ++	stop = jiffies + chip->vendor.timeout_d;
  1.1033 ++	do {
  1.1034 ++		burstcnt = ioread8(chip->vendor.iobase +
  1.1035 ++				   TPM_STS(chip->vendor.locality) + 1);
  1.1036 ++		burstcnt += ioread8(chip->vendor.iobase +
  1.1037 ++				    TPM_STS(chip->vendor.locality) +
  1.1038 ++				    2) << 8;
  1.1039 ++		if (burstcnt)
  1.1040 ++			return burstcnt;
  1.1041 ++		msleep(TPM_TIMEOUT);
  1.1042 ++	} while (time_before(jiffies, stop));
  1.1043 ++	return -EBUSY;
  1.1044 ++}
  1.1045 ++
  1.1046 ++static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
  1.1047 ++			 wait_queue_head_t *queue)
  1.1048 ++{
  1.1049 ++	unsigned long stop;
  1.1050 ++	long rc;
  1.1051 ++	u8 status;
  1.1052 ++
  1.1053 ++	/* check current status */
  1.1054 ++	status = tpm_tis_status(chip);
  1.1055 ++	if ((status & mask) == mask)
  1.1056 ++		return 0;
  1.1057 ++
  1.1058 ++	if (chip->vendor.irq) {
  1.1059 ++		rc = wait_event_interruptible_timeout(*queue,
  1.1060 ++						      ((tpm_tis_status
  1.1061 ++							(chip) & mask) ==
  1.1062 ++						       mask), timeout);
  1.1063 ++		if (rc > 0)
  1.1064 ++			return 0;
  1.1065 ++	} else {
  1.1066 ++		stop = jiffies + timeout;
  1.1067 ++		do {
  1.1068 ++			msleep(TPM_TIMEOUT);
  1.1069 ++			status = tpm_tis_status(chip);
  1.1070 ++			if ((status & mask) == mask)
  1.1071 ++				return 0;
  1.1072 ++		} while (time_before(jiffies, stop));
  1.1073 ++	}
  1.1074 ++	return -ETIME;
  1.1075 ++}
  1.1076 ++
  1.1077 ++static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  1.1078 ++{
  1.1079 ++	int size = 0, burstcnt;
  1.1080 ++	while (size < count &&
  1.1081 ++	       wait_for_stat(chip,
  1.1082 ++			     TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  1.1083 ++			     chip->vendor.timeout_c,
  1.1084 ++			     &chip->vendor.read_queue)
  1.1085 ++	       == 0) {
  1.1086 ++		burstcnt = get_burstcount(chip);
  1.1087 ++		for (; burstcnt > 0 && size < count; burstcnt--)
  1.1088 ++			buf[size++] = ioread8(chip->vendor.iobase +
  1.1089 ++					      TPM_DATA_FIFO(chip->vendor.
  1.1090 ++							    locality));
  1.1091 ++	}
  1.1092 ++	return size;
  1.1093 ++}
  1.1094 ++
  1.1095 ++static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  1.1096 ++{
  1.1097 ++	int size = 0;
  1.1098 ++	int expected, status;
  1.1099 ++
  1.1100 ++	if (count < TPM_HEADER_SIZE) {
  1.1101 ++		size = -EIO;
  1.1102 ++		goto out;
  1.1103 ++	}
  1.1104 ++
  1.1105 ++	/* read first 10 bytes, including tag, paramsize, and result */
  1.1106 ++	if ((size =
  1.1107 ++	     recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
  1.1108 ++		dev_err(chip->dev, "Unable to read header\n");
  1.1109 ++		goto out;
  1.1110 ++	}
  1.1111 ++
  1.1112 ++	expected = be32_to_cpu(*(__be32 *) (buf + 2));
  1.1113 ++	if (expected > count) {
  1.1114 ++		size = -EIO;
  1.1115 ++		goto out;
  1.1116 ++	}
  1.1117 ++
  1.1118 ++	if ((size +=
  1.1119 ++	     recv_data(chip, &buf[TPM_HEADER_SIZE],
  1.1120 ++		       expected - TPM_HEADER_SIZE)) < expected) {
  1.1121 ++		dev_err(chip->dev, "Unable to read remainder of result\n");
  1.1122 ++		size = -ETIME;
  1.1123 ++		goto out;
  1.1124 ++	}
  1.1125 ++
  1.1126 ++	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
  1.1127 ++		      &chip->vendor.int_queue);
  1.1128 ++	status = tpm_tis_status(chip);
  1.1129 ++	if (status & TPM_STS_DATA_AVAIL) {	/* retry? */
  1.1130 ++		dev_err(chip->dev, "Error left over data\n");
  1.1131 ++		size = -EIO;
  1.1132 ++		goto out;
  1.1133 ++	}
  1.1134 ++
  1.1135 ++out:
  1.1136 ++	tpm_tis_ready(chip);
  1.1137 ++	release_locality(chip, chip->vendor.locality, 0);
  1.1138 ++	return size;
  1.1139 ++}
  1.1140 ++
  1.1141 ++/*
  1.1142 ++ * If interrupts are used (signaled by an irq set in the vendor structure)
  1.1143 ++ * tpm.c can skip polling for the data to be available as the interrupt is
  1.1144 ++ * waited for here
  1.1145 ++ */
  1.1146 ++static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
  1.1147 ++{
  1.1148 ++	int rc, status, burstcnt;
  1.1149 ++	size_t count = 0;
  1.1150 ++	u32 ordinal;
  1.1151 ++
  1.1152 ++	if (request_locality(chip, 0) < 0)
  1.1153 ++		return -EBUSY;
  1.1154 ++
  1.1155 ++	status = tpm_tis_status(chip);
  1.1156 ++	if ((status & TPM_STS_COMMAND_READY) == 0) {
  1.1157 ++		tpm_tis_ready(chip);
  1.1158 ++		if (wait_for_stat
  1.1159 ++		    (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
  1.1160 ++		     &chip->vendor.int_queue) < 0) {
  1.1161 ++			rc = -ETIME;
  1.1162 ++			goto out_err;
  1.1163 ++		}
  1.1164 ++	}
  1.1165 ++
  1.1166 ++	while (count < len - 1) {
  1.1167 ++		burstcnt = get_burstcount(chip);
  1.1168 ++		for (; burstcnt > 0 && count < len - 1; burstcnt--) {
  1.1169 ++			iowrite8(buf[count], chip->vendor.iobase +
  1.1170 ++				 TPM_DATA_FIFO(chip->vendor.locality));
  1.1171 ++			count++;
  1.1172 ++		}
  1.1173 ++
  1.1174 ++		wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
  1.1175 ++			      &chip->vendor.int_queue);
  1.1176 ++		status = tpm_tis_status(chip);
  1.1177 ++		if ((status & TPM_STS_DATA_EXPECT) == 0) {
  1.1178 ++			rc = -EIO;
  1.1179 ++			goto out_err;
  1.1180 ++		}
  1.1181 ++	}
  1.1182 ++
  1.1183 ++	/* write last byte */
  1.1184 ++	iowrite8(buf[count],
  1.1185 ++		 chip->vendor.iobase +
  1.1186 ++		 TPM_DATA_FIFO(chip->vendor.locality));
  1.1187 ++	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
  1.1188 ++		      &chip->vendor.int_queue);
  1.1189 ++	status = tpm_tis_status(chip);
  1.1190 ++	if ((status & TPM_STS_DATA_EXPECT) != 0) {
  1.1191 ++		rc = -EIO;
  1.1192 ++		goto out_err;
  1.1193 ++	}
  1.1194 ++
  1.1195 ++	/* go and do it */
  1.1196 ++	iowrite8(TPM_STS_GO,
  1.1197 ++		 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
  1.1198 ++
  1.1199 ++	if (chip->vendor.irq) {
  1.1200 ++		ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
  1.1201 ++		if (wait_for_stat
  1.1202 ++		    (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  1.1203 ++		     tpm_calc_ordinal_duration(chip, ordinal),
  1.1204 ++		     &chip->vendor.read_queue) < 0) {
  1.1205 ++			rc = -ETIME;
  1.1206 ++			goto out_err;
  1.1207 ++		}
  1.1208 ++	}
  1.1209 ++	return len;
  1.1210 ++out_err:
  1.1211 ++	tpm_tis_ready(chip);
  1.1212 ++	release_locality(chip, chip->vendor.locality, 0);
  1.1213 ++	return rc;
  1.1214 ++}
  1.1215 ++
  1.1216 ++static struct file_operations tis_ops = {
  1.1217 ++	.owner = THIS_MODULE,
  1.1218 ++	.llseek = no_llseek,
  1.1219 ++	.open = tpm_open,
  1.1220 ++	.read = tpm_read,
  1.1221 ++	.write = tpm_write,
  1.1222 ++	.release = tpm_release,
  1.1223 ++};
  1.1224 ++
  1.1225 ++static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
  1.1226 ++static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
  1.1227 ++static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
  1.1228 ++static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
  1.1229 ++static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
  1.1230 ++static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
  1.1231 ++		   NULL);
  1.1232 ++static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
  1.1233 ++static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
  1.1234 ++
  1.1235 ++static struct attribute *tis_attrs[] = {
  1.1236 ++	&dev_attr_pubek.attr,
  1.1237 ++	&dev_attr_pcrs.attr,
  1.1238 ++	&dev_attr_enabled.attr,
  1.1239 ++	&dev_attr_active.attr,
  1.1240 ++	&dev_attr_owned.attr,
  1.1241 ++	&dev_attr_temp_deactivated.attr,
  1.1242 ++	&dev_attr_caps.attr,
  1.1243 ++	&dev_attr_cancel.attr, NULL,
  1.1244 ++};
  1.1245 ++
  1.1246 ++static struct attribute_group tis_attr_grp = {
  1.1247 ++	.attrs = tis_attrs
  1.1248 ++};
  1.1249 ++
  1.1250 ++static struct tpm_vendor_specific tpm_tis = {
  1.1251 ++	.status = tpm_tis_status,
  1.1252 ++	.recv = tpm_tis_recv,
  1.1253 ++	.send = tpm_tis_send,
  1.1254 ++	.cancel = tpm_tis_ready,
  1.1255 ++	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  1.1256 ++	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  1.1257 ++	.req_canceled = TPM_STS_COMMAND_READY,
  1.1258 ++	.attr_group = &tis_attr_grp,
  1.1259 ++	.miscdev = {
  1.1260 ++		    .fops = &tis_ops,},
  1.1261 ++};
  1.1262 ++
  1.1263 ++static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
  1.1264 ++{
  1.1265 ++	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
  1.1266 ++	u32 interrupt;
  1.1267 ++
  1.1268 ++	interrupt = ioread32(chip->vendor.iobase +
  1.1269 ++			     TPM_INT_STATUS(chip->vendor.locality));
  1.1270 ++
  1.1271 ++	if (interrupt == 0)
  1.1272 ++		return IRQ_NONE;
  1.1273 ++
  1.1274 ++	chip->vendor.irq = irq;
  1.1275 ++
  1.1276 ++	/* Clear interrupts handled with TPM_EOI */
  1.1277 ++	iowrite32(interrupt,
  1.1278 ++		  chip->vendor.iobase +
  1.1279 ++		  TPM_INT_STATUS(chip->vendor.locality));
  1.1280 ++	return IRQ_HANDLED;
  1.1281 ++}
  1.1282 ++
  1.1283 ++static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
  1.1284 ++{
  1.1285 ++	struct tpm_chip *chip = (struct tpm_chip *) dev_id;
  1.1286 ++	u32 interrupt;
  1.1287 ++	int i;
  1.1288 ++
  1.1289 ++	interrupt = ioread32(chip->vendor.iobase +
  1.1290 ++			     TPM_INT_STATUS(chip->vendor.locality));
  1.1291 ++
  1.1292 ++	if (interrupt == 0)
  1.1293 ++		return IRQ_NONE;
  1.1294 ++
  1.1295 ++	if (interrupt & TPM_INTF_DATA_AVAIL_INT)
  1.1296 ++		wake_up_interruptible(&chip->vendor.read_queue);
  1.1297 ++	if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
  1.1298 ++		for (i = 0; i < 5; i++)
  1.1299 ++			if (check_locality(chip, i) >= 0)
  1.1300 ++				break;
  1.1301 ++	if (interrupt &
  1.1302 ++	    (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
  1.1303 ++	     TPM_INTF_CMD_READY_INT))
  1.1304 ++		wake_up_interruptible(&chip->vendor.int_queue);
  1.1305 ++
  1.1306 ++	/* Clear interrupts handled with TPM_EOI */
  1.1307 ++	iowrite32(interrupt,
  1.1308 ++		  chip->vendor.iobase +
  1.1309 ++		  TPM_INT_STATUS(chip->vendor.locality));
  1.1310 ++	return IRQ_HANDLED;
  1.1311 ++}
  1.1312 ++
  1.1313 ++static int interrupts = 1;
  1.1314 ++module_param(interrupts, bool, 0444);
  1.1315 ++MODULE_PARM_DESC(interrupts, "Enable interrupts");
  1.1316 ++
  1.1317 ++static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
  1.1318 ++				      const struct pnp_device_id *pnp_id)
  1.1319 ++{
  1.1320 ++	u32 vendor, intfcaps, intmask;
  1.1321 ++	int rc, i;
  1.1322 ++	unsigned long start, len;
  1.1323 ++	struct tpm_chip *chip;
  1.1324 ++
  1.1325 ++	start = pnp_mem_start(pnp_dev, 0);
  1.1326 ++	len = pnp_mem_len(pnp_dev, 0);
  1.1327 ++
  1.1328 ++	if (!start)
  1.1329 ++		start = TIS_MEM_BASE;
  1.1330 ++	if (!len)
  1.1331 ++		len = TIS_MEM_LEN;
  1.1332 ++
  1.1333 ++	if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
  1.1334 ++		return -ENODEV;
  1.1335 ++
  1.1336 ++	chip->vendor.iobase = ioremap(start, len);
  1.1337 ++	if (!chip->vendor.iobase) {
  1.1338 ++		rc = -EIO;
  1.1339 ++		goto out_err;
  1.1340 ++	}
  1.1341 ++
  1.1342 ++	vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
  1.1343 ++
  1.1344 ++	/* Default timeouts */
  1.1345 ++	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
  1.1346 ++	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
  1.1347 ++	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
  1.1348 ++	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
  1.1349 ++
  1.1350 ++	dev_info(&pnp_dev->dev,
  1.1351 ++		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
  1.1352 ++		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
  1.1353 ++
  1.1354 ++	/* Figure out the capabilities */
  1.1355 ++	intfcaps =
  1.1356 ++	    ioread32(chip->vendor.iobase +
  1.1357 ++		     TPM_INTF_CAPS(chip->vendor.locality));
  1.1358 ++	dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
  1.1359 ++		intfcaps);
  1.1360 ++	if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
  1.1361 ++		dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
  1.1362 ++	if (intfcaps & TPM_INTF_CMD_READY_INT)
  1.1363 ++		dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
  1.1364 ++	if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
  1.1365 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
  1.1366 ++	if (intfcaps & TPM_INTF_INT_EDGE_RISING)
  1.1367 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
  1.1368 ++	if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
  1.1369 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
  1.1370 ++	if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
  1.1371 ++		dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
  1.1372 ++	if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
  1.1373 ++		dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
  1.1374 ++	if (intfcaps & TPM_INTF_STS_VALID_INT)
  1.1375 ++		dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
  1.1376 ++	if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
  1.1377 ++		dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
  1.1378 ++
  1.1379 ++	if (request_locality(chip, 0) != 0) {
  1.1380 ++		rc = -ENODEV;
  1.1381 ++		goto out_err;
  1.1382 ++	}
  1.1383 ++
  1.1384 ++	/* INTERRUPT Setup */
  1.1385 ++	init_waitqueue_head(&chip->vendor.read_queue);
  1.1386 ++	init_waitqueue_head(&chip->vendor.int_queue);
  1.1387 ++
  1.1388 ++	intmask =
  1.1389 ++	    ioread32(chip->vendor.iobase +
  1.1390 ++		     TPM_INT_ENABLE(chip->vendor.locality));
  1.1391 ++
  1.1392 ++	intmask |= TPM_INTF_CMD_READY_INT
  1.1393 ++	    | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
  1.1394 ++	    | TPM_INTF_STS_VALID_INT;
  1.1395 ++
  1.1396 ++	iowrite32(intmask,
  1.1397 ++		  chip->vendor.iobase +
  1.1398 ++		  TPM_INT_ENABLE(chip->vendor.locality));
  1.1399 ++	if (interrupts) {
  1.1400 ++		chip->vendor.irq =
  1.1401 ++		    ioread8(chip->vendor.iobase +
  1.1402 ++			    TPM_INT_VECTOR(chip->vendor.locality));
  1.1403 ++
  1.1404 ++		for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
  1.1405 ++			iowrite8(i, chip->vendor.iobase +
  1.1406 ++				    TPM_INT_VECTOR(chip->vendor.locality));
  1.1407 ++			if (request_irq
  1.1408 ++			    (i, tis_int_probe, SA_SHIRQ,
  1.1409 ++			     chip->vendor.miscdev.name, chip) != 0) {
  1.1410 ++				dev_info(chip->dev,
  1.1411 ++					 "Unable to request irq: %d for probe\n",
  1.1412 ++					 i);
  1.1413 ++				continue;
  1.1414 ++			}
  1.1415 ++
  1.1416 ++			/* Clear all existing */
  1.1417 ++			iowrite32(ioread32
  1.1418 ++				  (chip->vendor.iobase +
  1.1419 ++				   TPM_INT_STATUS(chip->vendor.locality)),
  1.1420 ++				  chip->vendor.iobase +
  1.1421 ++				  TPM_INT_STATUS(chip->vendor.locality));
  1.1422 ++
  1.1423 ++			/* Turn on */
  1.1424 ++			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
  1.1425 ++				  chip->vendor.iobase +
  1.1426 ++				  TPM_INT_ENABLE(chip->vendor.locality));
  1.1427 ++
  1.1428 ++			/* Generate Interrupts */
  1.1429 ++			tpm_gen_interrupt(chip);
  1.1430 ++
  1.1431 ++			/* Turn off */
  1.1432 ++			iowrite32(intmask,
  1.1433 ++				  chip->vendor.iobase +
  1.1434 ++				  TPM_INT_ENABLE(chip->vendor.locality));
  1.1435 ++			free_irq(i, chip);
  1.1436 ++		}
  1.1437 ++	}
  1.1438 ++	if (chip->vendor.irq) {
  1.1439 ++		iowrite8(chip->vendor.irq,
  1.1440 ++			 chip->vendor.iobase +
  1.1441 ++			 TPM_INT_VECTOR(chip->vendor.locality));
  1.1442 ++		if (request_irq
  1.1443 ++		    (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
  1.1444 ++		     chip->vendor.miscdev.name, chip) != 0) {
  1.1445 ++			dev_info(chip->dev,
  1.1446 ++				 "Unable to request irq: %d for use\n",
  1.1447 ++				 chip->vendor.irq);
  1.1448 ++			chip->vendor.irq = 0;
  1.1449 ++		} else {
  1.1450 ++			/* Clear all existing */
  1.1451 ++			iowrite32(ioread32
  1.1452 ++				  (chip->vendor.iobase +
  1.1453 ++				   TPM_INT_STATUS(chip->vendor.locality)),
  1.1454 ++				  chip->vendor.iobase +
  1.1455 ++				  TPM_INT_STATUS(chip->vendor.locality));
  1.1456 ++
  1.1457 ++			/* Turn on */
  1.1458 ++			iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
  1.1459 ++				  chip->vendor.iobase +
  1.1460 ++				  TPM_INT_ENABLE(chip->vendor.locality));
  1.1461 ++		}
  1.1462 ++	}
  1.1463 ++
  1.1464 ++	INIT_LIST_HEAD(&chip->vendor.list);
  1.1465 ++	spin_lock(&tis_lock);
  1.1466 ++	list_add(&chip->vendor.list, &tis_chips);
  1.1467 ++	spin_unlock(&tis_lock);
  1.1468 ++
  1.1469 ++	tpm_get_timeouts(chip);
  1.1470 ++	tpm_continue_selftest(chip);
  1.1471 ++
  1.1472 ++	return 0;
  1.1473 ++out_err:
  1.1474 ++	if (chip->vendor.iobase)
  1.1475 ++		iounmap(chip->vendor.iobase);
  1.1476 ++	tpm_remove_hardware(chip->dev);
  1.1477 ++	return rc;
  1.1478 ++}
  1.1479 ++
  1.1480 ++static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
  1.1481 ++{
  1.1482 ++	return tpm_pm_suspend(&dev->dev, msg);
  1.1483 ++}
  1.1484 ++
  1.1485 ++static int tpm_tis_pnp_resume(struct pnp_dev *dev)
  1.1486 ++{
  1.1487 ++	return tpm_pm_resume(&dev->dev);
  1.1488 ++}
  1.1489 ++
  1.1490 ++static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
  1.1491 ++	{"PNP0C31", 0},		/* TPM */
  1.1492 ++	{"ATM1200", 0},		/* Atmel */
  1.1493 ++	{"IFX0102", 0},		/* Infineon */
  1.1494 ++	{"BCM0101", 0},		/* Broadcom */
  1.1495 ++	{"NSC1200", 0},		/* National */
  1.1496 ++	/* Add new here */
  1.1497 ++	{"", 0},		/* User Specified */
  1.1498 ++	{"", 0}			/* Terminator */
  1.1499 ++};
  1.1500 ++
  1.1501 ++static struct pnp_driver tis_pnp_driver = {
  1.1502 ++	.name = "tpm_tis",
  1.1503 ++	.id_table = tpm_pnp_tbl,
  1.1504 ++	.probe = tpm_tis_pnp_init,
  1.1505 ++	.suspend = tpm_tis_pnp_suspend,
  1.1506 ++	.resume = tpm_tis_pnp_resume,
  1.1507 ++};
  1.1508 ++
  1.1509 ++#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
  1.1510 ++module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
  1.1511 ++		    sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
  1.1512 ++MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
  1.1513 ++
  1.1514 ++static int __init init_tis(void)
  1.1515 ++{
  1.1516 ++	return pnp_register_driver(&tis_pnp_driver);
  1.1517 ++}
  1.1518 ++
  1.1519 ++static void __exit cleanup_tis(void)
  1.1520 ++{
  1.1521 ++	struct tpm_vendor_specific *i, *j;
  1.1522 ++	struct tpm_chip *chip;
  1.1523 ++	spin_lock(&tis_lock);
  1.1524 ++	list_for_each_entry_safe(i, j, &tis_chips, list) {
  1.1525 ++		chip = to_tpm_chip(i);
  1.1526 ++		iowrite32(~TPM_GLOBAL_INT_ENABLE &
  1.1527 ++			  ioread32(chip->vendor.iobase +
  1.1528 ++				   TPM_INT_ENABLE(chip->vendor.
  1.1529 ++						  locality)),
  1.1530 ++			  chip->vendor.iobase +
  1.1531 ++			  TPM_INT_ENABLE(chip->vendor.locality));
  1.1532 ++		release_locality(chip, chip->vendor.locality, 1);
  1.1533 ++		if (chip->vendor.irq)
  1.1534 ++			free_irq(chip->vendor.irq, chip);
  1.1535 ++		iounmap(i->iobase);
  1.1536 ++		list_del(&i->list);
  1.1537 ++		tpm_remove_hardware(chip->dev);
  1.1538 ++	}
  1.1539 ++	spin_unlock(&tis_lock);
  1.1540 ++	pnp_unregister_driver(&tis_pnp_driver);
  1.1541 ++}
  1.1542 ++
  1.1543 ++module_init(init_tis);
  1.1544 ++module_exit(cleanup_tis);
  1.1545 ++MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
  1.1546 ++MODULE_DESCRIPTION("TPM Driver");
  1.1547 ++MODULE_VERSION("2.0");
  1.1548 ++MODULE_LICENSE("GPL");
  1.1549 +