aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm
diff options
context:
space:
mode:
authorLeendert van Doorn <leendert@watson.ibm.com>2006-04-22 05:38:03 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-22 12:19:54 -0400
commit27084efee0c3dc0eb15b5ed750aa9f1adb3983c3 (patch)
treeaa9570006e4e44e3f9a1c2c1960ed025a790711c /drivers/char/tpm
parent08e96e486dd1345ae0ad70247387d0d4fd346889 (diff)
[PATCH] tpm: driver for next generation TPM chips
The driver for the next generation of TPM chips version 1.2 including support for interrupts. The Trusted Computing Group has written the TPM Interface Specification (TIS) which defines a common interface for all manufacturer's 1.2 TPM's thus the name tpm_tis. Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com> Signed-off-by: Kylene Hall <kjhall@us.ibm.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r--drivers/char/tpm/Kconfig11
-rw-r--r--drivers/char/tpm/Makefile1
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/char/tpm/tpm.h9
-rw-r--r--drivers/char/tpm/tpm_tis.c647
5 files changed, 670 insertions, 1 deletions
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index a6873bf89ffa..1efde3b27619 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -20,9 +20,18 @@ config TCG_TPM
20 Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI 20 Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
21 and CONFIG_PNPACPI. 21 and CONFIG_PNPACPI.
22 22
23config TCG_TIS
24 tristate "TPM Interface Specification 1.2 Interface"
25 depends on TCG_TPM
26 ---help---
27 If you have a TPM security chip that is compliant with the
28 TCG TIS 1.2 TPM specification say Yes and it will be accessible
29 from within Linux. To compile this driver as a module, choose
30 M here; the module will be called tpm_tis.
31
23config TCG_NSC 32config TCG_NSC
24 tristate "National Semiconductor TPM Interface" 33 tristate "National Semiconductor TPM Interface"
25 depends on TCG_TPM 34 depends on TCG_TPM && PNPACPI
26 ---help--- 35 ---help---
27 If you have a TPM security chip from National Semicondutor 36 If you have a TPM security chip from National Semicondutor
28 say Yes and it will be accessible from within Linux. To 37 say Yes and it will be accessible from within Linux. To
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index ba4582d160fd..ea3a1e02a824 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o
5ifdef CONFIG_ACPI 5ifdef CONFIG_ACPI
6 obj-$(CONFIG_TCG_TPM) += tpm_bios.o 6 obj-$(CONFIG_TCG_TPM) += tpm_bios.o
7endif 7endif
8obj-$(CONFIG_TCG_TIS) += tpm_tis.o
8obj-$(CONFIG_TCG_NSC) += tpm_nsc.o 9obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
9obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o 10obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
10obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o 11obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 24c4423d4851..150c86af7809 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -390,6 +390,9 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
390 goto out; 390 goto out;
391 } 391 }
392 392
393 if (chip->vendor.irq)
394 goto out_recv;
395
393 stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal); 396 stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
394 do { 397 do {
395 u8 status = chip->vendor.status(chip); 398 u8 status = chip->vendor.status(chip);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 75d105c4e65d..24541a556d02 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -64,6 +64,8 @@ struct tpm_vendor_specific {
64 void __iomem *iobase; /* ioremapped address */ 64 void __iomem *iobase; /* ioremapped address */
65 unsigned long base; /* TPM base address */ 65 unsigned long base; /* TPM base address */
66 66
67 int irq;
68
67 int region_size; 69 int region_size;
68 int have_region; 70 int have_region;
69 71
@@ -73,8 +75,13 @@ struct tpm_vendor_specific {
73 u8 (*status) (struct tpm_chip *); 75 u8 (*status) (struct tpm_chip *);
74 struct miscdevice miscdev; 76 struct miscdevice miscdev;
75 struct attribute_group *attr_group; 77 struct attribute_group *attr_group;
78 struct list_head list;
79 int locality;
76 u32 timeout_a, timeout_b, timeout_c, timeout_d; 80 u32 timeout_a, timeout_b, timeout_c, timeout_d;
77 u32 duration[3]; 81 u32 duration[3];
82
83 wait_queue_head_t read_queue;
84 wait_queue_head_t int_queue;
78}; 85};
79 86
80struct tpm_chip { 87struct tpm_chip {
@@ -100,6 +107,8 @@ struct tpm_chip {
100 struct list_head list; 107 struct list_head list;
101}; 108};
102 109
110#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
111
103static inline int tpm_read_index(int base, int index) 112static inline int tpm_read_index(int base, int index)
104{ 113{
105 outb(index, base); 114 outb(index, base);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
new file mode 100644
index 000000000000..02759307f736
--- /dev/null
+++ b/drivers/char/tpm/tpm_tis.c
@@ -0,0 +1,647 @@
1/*
2 * Copyright (C) 2005, 2006 IBM Corporation
3 *
4 * Authors:
5 * Leendert van Doorn <leendert@watson.ibm.com>
6 * Kylene Hall <kjhall@us.ibm.com>
7 *
8 * Device driver for TCG/TCPA TPM (trusted platform module).
9 * Specifications at www.trustedcomputinggroup.org
10 *
11 * This device driver implements the TPM interface as defined in
12 * the TCG TPM Interface Spec version 1.2, revision 1.0.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation, version 2 of the
17 * License.
18 */
19#include <linux/pnp.h>
20#include <linux/interrupt.h>
21#include <linux/wait.h>
22#include "tpm.h"
23
24#define TPM_HEADER_SIZE 10
25
26enum tis_access {
27 TPM_ACCESS_VALID = 0x80,
28 TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
29 TPM_ACCESS_REQUEST_PENDING = 0x04,
30 TPM_ACCESS_REQUEST_USE = 0x02,
31};
32
33enum tis_status {
34 TPM_STS_VALID = 0x80,
35 TPM_STS_COMMAND_READY = 0x40,
36 TPM_STS_GO = 0x20,
37 TPM_STS_DATA_AVAIL = 0x10,
38 TPM_STS_DATA_EXPECT = 0x08,
39};
40
41enum tis_int_flags {
42 TPM_GLOBAL_INT_ENABLE = 0x80000000,
43 TPM_INTF_BURST_COUNT_STATIC = 0x100,
44 TPM_INTF_CMD_READY_INT = 0x080,
45 TPM_INTF_INT_EDGE_FALLING = 0x040,
46 TPM_INTF_INT_EDGE_RISING = 0x020,
47 TPM_INTF_INT_LEVEL_LOW = 0x010,
48 TPM_INTF_INT_LEVEL_HIGH = 0x008,
49 TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
50 TPM_INTF_STS_VALID_INT = 0x002,
51 TPM_INTF_DATA_AVAIL_INT = 0x001,
52};
53
54#define TPM_ACCESS(l) (0x0000 | ((l) << 12))
55#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12))
56#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12))
57#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12))
58#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12))
59#define TPM_STS(l) (0x0018 | ((l) << 12))
60#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12))
61
62#define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
63#define TPM_RID(l) (0x0F04 | ((l) << 12))
64
65static LIST_HEAD(tis_chips);
66static DEFINE_SPINLOCK(tis_lock);
67
68static int check_locality(struct tpm_chip *chip, int l)
69{
70 if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
71 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
72 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
73 return chip->vendor.locality = l;
74
75 return -1;
76}
77
78static void release_locality(struct tpm_chip *chip, int l, int force)
79{
80 if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
81 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
82 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
83 iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
84 chip->vendor.iobase + TPM_ACCESS(l));
85}
86
87static int request_locality(struct tpm_chip *chip, int l)
88{
89 unsigned long stop;
90 long rc;
91
92 if (check_locality(chip, l) >= 0)
93 return l;
94
95 iowrite8(TPM_ACCESS_REQUEST_USE,
96 chip->vendor.iobase + TPM_ACCESS(l));
97
98 if (chip->vendor.irq) {
99 rc = wait_event_interruptible_timeout(chip->vendor.
100 int_queue,
101 (check_locality
102 (chip, l) >= 0),
103 msecs_to_jiffies
104 (chip->vendor.
105 timeout_a));
106 if (rc > 0)
107 return l;
108
109 } else {
110 /* wait for burstcount */
111 stop = jiffies + (HZ * chip->vendor.timeout_a / 1000);
112 do {
113 if (check_locality(chip, l) >= 0)
114 return l;
115 msleep(TPM_TIMEOUT);
116 }
117 while (time_before(jiffies, stop));
118 }
119 return -1;
120}
121
122static u8 tpm_tis_status(struct tpm_chip *chip)
123{
124 return ioread8(chip->vendor.iobase +
125 TPM_STS(chip->vendor.locality));
126}
127
128static void tpm_tis_ready(struct tpm_chip *chip)
129{
130 /* this causes the current command to be aborted */
131 iowrite8(TPM_STS_COMMAND_READY,
132 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
133}
134
135static int get_burstcount(struct tpm_chip *chip)
136{
137 unsigned long stop;
138 int burstcnt;
139
140 /* wait for burstcount */
141 /* which timeout value, spec has 2 answers (c & d) */
142 stop = jiffies + (HZ * chip->vendor.timeout_d / 1000);
143 do {
144 burstcnt = ioread8(chip->vendor.iobase +
145 TPM_STS(chip->vendor.locality) + 1);
146 burstcnt += ioread8(chip->vendor.iobase +
147 TPM_STS(chip->vendor.locality) +
148 2) << 8;
149 if (burstcnt)
150 return burstcnt;
151 msleep(TPM_TIMEOUT);
152 } while (time_before(jiffies, stop));
153 return -EBUSY;
154}
155
156static int wait_for_stat(struct tpm_chip *chip, u8 mask, u32 timeout,
157 wait_queue_head_t *queue)
158{
159 unsigned long stop;
160 long rc;
161 u8 status;
162
163 /* check current status */
164 status = tpm_tis_status(chip);
165 if ((status & mask) == mask)
166 return 0;
167
168 if (chip->vendor.irq) {
169 rc = wait_event_interruptible_timeout(*queue,
170 ((tpm_tis_status
171 (chip) & mask) ==
172 mask),
173 msecs_to_jiffies
174 (timeout));
175 if (rc > 0)
176 return 0;
177 } else {
178 stop = jiffies + (HZ * timeout / 1000);
179 do {
180 msleep(TPM_TIMEOUT);
181 status = tpm_tis_status(chip);
182 if ((status & mask) == mask)
183 return 0;
184 } while (time_before(jiffies, stop));
185 }
186 return -ETIME;
187}
188
189static int recv_data(struct tpm_chip *chip, u8 * buf, size_t count)
190{
191 int size = 0, burstcnt;
192 while (size < count &&
193 wait_for_stat(chip,
194 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
195 chip->vendor.timeout_c,
196 &chip->vendor.read_queue)
197 == 0) {
198 burstcnt = get_burstcount(chip);
199 for (; burstcnt > 0 && size < count; burstcnt--)
200 buf[size++] = ioread8(chip->vendor.iobase +
201 TPM_DATA_FIFO(chip->vendor.
202 locality));
203 }
204 return size;
205}
206
207static int tpm_tis_recv(struct tpm_chip *chip, u8 * buf, size_t count)
208{
209 int size = 0;
210 int expected, status;
211
212 if (count < TPM_HEADER_SIZE) {
213 size = -EIO;
214 goto out;
215 }
216
217 /* read first 10 bytes, including tag, paramsize, and result */
218 if ((size =
219 recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
220 dev_err(chip->dev, "Unable to read header\n");
221 goto out;
222 }
223
224 expected = be32_to_cpu(*(__be32 *) (buf + 2));
225 if (expected > count) {
226 size = -EIO;
227 goto out;
228 }
229
230 if ((size +=
231 recv_data(chip, &buf[TPM_HEADER_SIZE],
232 expected - TPM_HEADER_SIZE)) < expected) {
233 dev_err(chip->dev, "Unable to read remainder of result\n");
234 size = -ETIME;
235 goto out;
236 }
237
238 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
239 &chip->vendor.int_queue);
240 status = tpm_tis_status(chip);
241 if (status & TPM_STS_DATA_AVAIL) { /* retry? */
242 dev_err(chip->dev, "Error left over data\n");
243 size = -EIO;
244 goto out;
245 }
246
247out:
248 tpm_tis_ready(chip);
249 release_locality(chip, chip->vendor.locality, 0);
250 return size;
251}
252
253/*
254 * If interrupts are used (signaled by an irq set in the vendor structure)
255 * tpm.c can skip polling for the data to be available as the interrupt is
256 * waited for here
257 */
258static int tpm_tis_send(struct tpm_chip *chip, u8 * buf, size_t len)
259{
260 int rc, status, burstcnt;
261 size_t count = 0;
262 u32 ordinal;
263
264 if (request_locality(chip, 0) < 0)
265 return -EBUSY;
266
267 status = tpm_tis_status(chip);
268 if ((status & TPM_STS_COMMAND_READY) == 0) {
269 tpm_tis_ready(chip);
270 if (wait_for_stat
271 (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
272 &chip->vendor.int_queue) < 0) {
273 rc = -ETIME;
274 goto out_err;
275 }
276 }
277
278 while (count < len - 1) {
279 burstcnt = get_burstcount(chip);
280 for (; burstcnt > 0 && count < len - 1; burstcnt--) {
281 iowrite8(buf[count], chip->vendor.iobase +
282 TPM_DATA_FIFO(chip->vendor.locality));
283 count++;
284 }
285
286 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
287 &chip->vendor.int_queue);
288 status = tpm_tis_status(chip);
289 if ((status & TPM_STS_DATA_EXPECT) == 0) {
290 rc = -EIO;
291 goto out_err;
292 }
293 }
294
295 /* write last byte */
296 iowrite8(buf[count],
297 chip->vendor.iobase +
298 TPM_DATA_FIFO(chip->vendor.locality));
299 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
300 &chip->vendor.int_queue);
301 status = tpm_tis_status(chip);
302 if ((status & TPM_STS_DATA_EXPECT) != 0) {
303 rc = -EIO;
304 goto out_err;
305 }
306
307 /* go and do it */
308 iowrite8(TPM_STS_GO,
309 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
310
311 if (chip->vendor.irq) {
312 ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
313 if (wait_for_stat
314 (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
315 tpm_calc_ordinal_duration(chip, ordinal),
316 &chip->vendor.read_queue) < 0) {
317 rc = -ETIME;
318 goto out_err;
319 }
320 }
321 return len;
322out_err:
323 tpm_tis_ready(chip);
324 release_locality(chip, chip->vendor.locality, 0);
325 return rc;
326}
327
328static struct file_operations tis_ops = {
329 .owner = THIS_MODULE,
330 .llseek = no_llseek,
331 .open = tpm_open,
332 .read = tpm_read,
333 .write = tpm_write,
334 .release = tpm_release,
335};
336
337static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
338static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
339static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
340static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
341static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
342static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
343 NULL);
344static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
345static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
346
347static struct attribute *tis_attrs[] = {
348 &dev_attr_pubek.attr,
349 &dev_attr_pcrs.attr,
350 &dev_attr_enabled.attr,
351 &dev_attr_active.attr,
352 &dev_attr_owned.attr,
353 &dev_attr_temp_deactivated.attr,
354 &dev_attr_caps.attr,
355 &dev_attr_cancel.attr, NULL,
356};
357
358static struct attribute_group tis_attr_grp = {
359 .attrs = tis_attrs
360};
361
362static struct tpm_vendor_specific tpm_tis = {
363 .status = tpm_tis_status,
364 .recv = tpm_tis_recv,
365 .send = tpm_tis_send,
366 .cancel = tpm_tis_ready,
367 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
368 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
369 .req_canceled = TPM_STS_COMMAND_READY,
370 .attr_group = &tis_attr_grp,
371 .miscdev = {
372 .fops = &tis_ops,},
373};
374
375static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs
376 *regs)
377{
378 struct tpm_chip *chip = (struct tpm_chip *) dev_id;
379 u32 interrupt;
380
381 interrupt = ioread32(chip->vendor.iobase +
382 TPM_INT_STATUS(chip->vendor.locality));
383
384 if (interrupt == 0)
385 return IRQ_NONE;
386
387 chip->vendor.irq = irq;
388
389 /* Clear interrupts handled with TPM_EOI */
390 iowrite32(interrupt,
391 chip->vendor.iobase +
392 TPM_INT_STATUS(chip->vendor.locality));
393 return IRQ_HANDLED;
394}
395
396static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs
397 *regs)
398{
399 struct tpm_chip *chip = (struct tpm_chip *) dev_id;
400 u32 interrupt;
401 int i;
402
403 interrupt = ioread32(chip->vendor.iobase +
404 TPM_INT_STATUS(chip->vendor.locality));
405
406 if (interrupt == 0)
407 return IRQ_NONE;
408
409 if (interrupt & TPM_INTF_DATA_AVAIL_INT)
410 wake_up_interruptible(&chip->vendor.read_queue);
411 if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
412 for (i = 0; i < 5; i++)
413 if (check_locality(chip, i) >= 0)
414 break;
415 if (interrupt &
416 (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
417 TPM_INTF_CMD_READY_INT))
418 wake_up_interruptible(&chip->vendor.int_queue);
419
420 /* Clear interrupts handled with TPM_EOI */
421 iowrite32(interrupt,
422 chip->vendor.iobase +
423 TPM_INT_STATUS(chip->vendor.locality));
424 return IRQ_HANDLED;
425}
426
427static int __devinit tpm_tis_pnp_init(struct pnp_dev
428 *pnp_dev, const struct
429 pnp_device_id
430 *pnp_id)
431{
432 u32 vendor, intfcaps, intmask;
433 int rc, i;
434 unsigned long start, len;
435 struct tpm_chip *chip;
436
437 start = pnp_mem_start(pnp_dev, 0);
438 len = pnp_mem_len(pnp_dev, 0);
439
440 if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
441 return -ENODEV;
442
443 chip->vendor.iobase = ioremap(start, len);
444 if (!chip->vendor.iobase) {
445 rc = -EIO;
446 goto out_err;
447 }
448
449 vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
450 if ((vendor & 0xFFFF) == 0xFFFF) {
451 rc = -ENODEV;
452 goto out_err;
453 }
454
455 /* Default timeouts */
456 chip->vendor.timeout_a = 750; /* ms */
457 chip->vendor.timeout_b = 2000; /* 2 sec */
458 chip->vendor.timeout_c = 750; /* ms */
459 chip->vendor.timeout_d = 750; /* ms */
460
461 dev_info(&pnp_dev->dev,
462 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
463 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
464
465 /* Figure out the capabilities */
466 intfcaps =
467 ioread32(chip->vendor.iobase +
468 TPM_INTF_CAPS(chip->vendor.locality));
469 dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
470 intfcaps);
471 if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
472 dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
473 if (intfcaps & TPM_INTF_CMD_READY_INT)
474 dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
475 if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
476 dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
477 if (intfcaps & TPM_INTF_INT_EDGE_RISING)
478 dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
479 if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
480 dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
481 if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
482 dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
483 if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
484 dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
485 if (intfcaps & TPM_INTF_STS_VALID_INT)
486 dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
487 if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
488 dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
489
490 if (request_locality(chip, 0) != 0) {
491 rc = -ENODEV;
492 goto out_err;
493 }
494
495 /* INTERRUPT Setup */
496 init_waitqueue_head(&chip->vendor.read_queue);
497 init_waitqueue_head(&chip->vendor.int_queue);
498
499 intmask =
500 ioread32(chip->vendor.iobase +
501 TPM_INT_ENABLE(chip->vendor.locality));
502
503 intmask |= TPM_INTF_CMD_READY_INT
504 | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
505 | TPM_INTF_STS_VALID_INT;
506
507 iowrite32(intmask,
508 chip->vendor.iobase +
509 TPM_INT_ENABLE(chip->vendor.locality));
510
511 chip->vendor.irq =
512 ioread8(chip->vendor.iobase +
513 TPM_INT_VECTOR(chip->vendor.locality));
514
515 for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
516 iowrite8(i,
517 chip->vendor.iobase +
518 TPM_INT_VECTOR(chip->vendor.locality));
519 if (request_irq
520 (i, tis_int_probe, SA_SHIRQ,
521 chip->vendor.miscdev.name, chip) != 0) {
522 dev_info(chip->dev,
523 "Unable to request irq: %d for probe\n",
524 i);
525 continue;
526 }
527
528 /* Clear all existing */
529 iowrite32(ioread32
530 (chip->vendor.iobase +
531 TPM_INT_STATUS(chip->vendor.locality)),
532 chip->vendor.iobase +
533 TPM_INT_STATUS(chip->vendor.locality));
534
535 /* Turn on */
536 iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
537 chip->vendor.iobase +
538 TPM_INT_ENABLE(chip->vendor.locality));
539
540 /* Generate Interrupts */
541 tpm_gen_interrupt(chip);
542
543 /* Turn off */
544 iowrite32(intmask,
545 chip->vendor.iobase +
546 TPM_INT_ENABLE(chip->vendor.locality));
547 free_irq(i, chip);
548 }
549 if (chip->vendor.irq) {
550 iowrite8(chip->vendor.irq,
551 chip->vendor.iobase +
552 TPM_INT_VECTOR(chip->vendor.locality));
553 if (request_irq
554 (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
555 chip->vendor.miscdev.name, chip) != 0) {
556 dev_info(chip->dev,
557 "Unable to request irq: %d for use\n", i);
558 chip->vendor.irq = 0;
559 } else {
560 /* Clear all existing */
561 iowrite32(ioread32
562 (chip->vendor.iobase +
563 TPM_INT_STATUS(chip->vendor.locality)),
564 chip->vendor.iobase +
565 TPM_INT_STATUS(chip->vendor.locality));
566
567 /* Turn on */
568 iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
569 chip->vendor.iobase +
570 TPM_INT_ENABLE(chip->vendor.locality));
571 }
572 }
573
574 INIT_LIST_HEAD(&chip->vendor.list);
575 spin_lock(&tis_lock);
576 list_add(&chip->vendor.list, &tis_chips);
577 spin_unlock(&tis_lock);
578
579 tpm_get_timeouts(chip);
580 tpm_continue_selftest(chip);
581
582 return 0;
583out_err:
584 if (chip->vendor.iobase)
585 iounmap(chip->vendor.iobase);
586 tpm_remove_hardware(chip->dev);
587 return rc;
588}
589
590static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
591{
592 return tpm_pm_suspend(&dev->dev, msg);
593}
594
595static int tpm_tis_pnp_resume(struct pnp_dev *dev)
596{
597 return tpm_pm_resume(&dev->dev);
598}
599
600static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
601 {"PNP0C31", 0}, /* TPM */
602 {"", 0}
603};
604
605static struct pnp_driver tis_pnp_driver = {
606 .name = "tpm_tis",
607 .id_table = tpm_pnp_tbl,
608 .probe = tpm_tis_pnp_init,
609 .suspend = tpm_tis_pnp_suspend,
610 .resume = tpm_tis_pnp_resume,
611};
612
613static int __init init_tis(void)
614{
615 return pnp_register_driver(&tis_pnp_driver);
616}
617
618static void __exit cleanup_tis(void)
619{
620 struct tpm_vendor_specific *i, *j;
621 struct tpm_chip *chip;
622 spin_lock(&tis_lock);
623 list_for_each_entry_safe(i, j, &tis_chips, list) {
624 chip = to_tpm_chip(i);
625 iowrite32(~TPM_GLOBAL_INT_ENABLE &
626 ioread32(chip->vendor.iobase +
627 TPM_INT_ENABLE(chip->vendor.
628 locality)),
629 chip->vendor.iobase +
630 TPM_INT_ENABLE(chip->vendor.locality));
631 release_locality(chip, chip->vendor.locality, 1);
632 if (chip->vendor.irq)
633 free_irq(chip->vendor.irq, chip);
634 iounmap(i->iobase);
635 list_del(&i->list);
636 tpm_remove_hardware(chip->dev);
637 }
638 spin_unlock(&tis_lock);
639 pnp_unregister_driver(&tis_pnp_driver);
640}
641
642module_init(init_tis);
643module_exit(cleanup_tis);
644MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
645MODULE_DESCRIPTION("TPM Driver");
646MODULE_VERSION("2.0");
647MODULE_LICENSE("GPL");