aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Huewe <peter.huewe@infineon.com>2012-08-07 05:42:32 -0400
committerKent Yoder <key@linux.vnet.ibm.com>2012-08-22 12:11:13 -0400
commitaad628c1d91a6db57e572e4c1f35e863d81061d7 (patch)
tree0dec330d0899c7f0e550aff745b65fd111be6d9e
parent51b743fe87d7fb3dba7a2ff4a1fe23bb65dc2245 (diff)
char/tpm: Add new driver for Infineon I2C TIS TPM
This patch adds a driver to support Infineon's SLB 9635 TT 1.2 Soft I2C TPMs which follow the TGC TIS 1.2 TPM specification[1] and Infineon's I2C Protocol Stack Specification 0.20. The I2C Protocol Stack Specification is a simple adaption of the LPC TIS Protocol to the I2C Bus. The I2C TPMs can be used when LPC Bus is not available (i.e. non x86 architectures like ARM). The driver is based on the tpm_tis.c driver by Leendert van Dorn and Kyleen Hall and has quite similar functionality. Tested on Nvidia ARM Tegra2 Development Platform and Beagleboard (ARM OMAP) Tested with the Trousers[2] TSS API Testsuite v 0.3 [3] Compile-tested on x86 (32/64-bit) Updates since version 2.1.4: - included "Lock the I2C adapter for a sequence of requests", by Bryan Freed - use __i2c_transfer instead of own implementation of unlocked i2c_transfer - use struct dev_pm_ops for power management via SIMPLE_DEV_PM_OPS Updates since version 2.1.3: - use proper probing mechanism * either add the tpm using I2C_BOARD_INFO to your board file or probe it * during runtime e.g on BeagleBoard using : * "echo tpm_i2c_infineon 0x20 > /sys/bus/i2c/devices/i2c-2/new_device" - fix possible endless loop if hardware misbehaves - improved return codes - consistent spelling i2c/tpm -> I2C/TPM - remove hardcoded sleep values and msleep usage - removed debug statements - added check for I2C functionality - renaming to tpm_i2c_infineon Updates since version 2.1.2: - added sysfs entries for duration and timeouts - updated to new tpm_do_selftest Updates since version 2.1.0: - improved error handling - implemented workarounds needed by the tpm - fixed typos References: [1] http://www.trustedcomputinggroup.org/resources/pc_client_work_group_pc_client_ specific_tpm_interface_specification_tis_version_12/ [2] http://trousers.sourceforge.net/ [3] http://sourceforge.net/projects/trousers/files/TSS%20API%20test%20suite/0.3/ Reviewed-by: Andi Shyti <andi.shyti@gmail.com> Acked-by: Marcel Selhorst <tpmdd@selhorst.net> Signed-off-by: Peter Huewe <peter.huewe@infineon.com> Signed-off-by: Bryan Freed <bfreed@chromium.org> Signed-off-by: Kent Yoder <key@linux.vnet.ibm.com>
-rw-r--r--drivers/char/tpm/Kconfig11
-rw-r--r--drivers/char/tpm/Makefile1
-rw-r--r--drivers/char/tpm/tpm_i2c_infineon.c695
3 files changed, 707 insertions, 0 deletions
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index a048199ce866..c4aac486ade5 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -33,6 +33,17 @@ config TCG_TIS
33 from within Linux. To compile this driver as a module, choose 33 from within Linux. To compile this driver as a module, choose
34 M here; the module will be called tpm_tis. 34 M here; the module will be called tpm_tis.
35 35
36config TCG_TIS_I2C_INFINEON
37 tristate "TPM Interface Specification 1.2 Interface (I2C - Infineon)"
38 depends on I2C
39 ---help---
40 If you have a TPM security chip that is compliant with the
41 TCG TIS 1.2 TPM specification and Infineon's I2C Protocol Stack
42 Specification 0.20 say Yes and it will be accessible from within
43 Linux.
44 To compile this driver as a module, choose M here; the module
45 will be called tpm_tis_i2c_infineon.
46
36config TCG_NSC 47config TCG_NSC
37 tristate "National Semiconductor TPM Interface" 48 tristate "National Semiconductor TPM Interface"
38 depends on X86 49 depends on X86
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index ea3a1e02a824..a9c3afc92dbc 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -6,6 +6,7 @@ ifdef 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_TIS) += tpm_tis.o
9obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o
9obj-$(CONFIG_TCG_NSC) += tpm_nsc.o 10obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
10obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o 11obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
11obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o 12obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c
new file mode 100644
index 000000000000..5a831aec9d4b
--- /dev/null
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -0,0 +1,695 @@
1/*
2 * Copyright (C) 2012 Infineon Technologies
3 *
4 * Authors:
5 * Peter Huewe <peter.huewe@infineon.com>
6 *
7 * Device driver for TCG/TCPA TPM (trusted platform module).
8 * Specifications at www.trustedcomputinggroup.org
9 *
10 * This device driver implements the TPM interface as defined in
11 * the TCG TPM Interface Spec version 1.2, revision 1.0 and the
12 * Infineon I2C Protocol Stack Specification v0.20.
13 *
14 * It is based on the original tpm_tis device driver from Leendert van
15 * Dorn and Kyleen Hall.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation, version 2 of the
20 * License.
21 *
22 *
23 */
24#include <linux/init.h>
25#include <linux/i2c.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/wait.h>
29#include "tpm.h"
30
31/* max. buffer size supported by our TPM */
32#define TPM_BUFSIZE 1260
33
34/* max. number of iterations after I2C NAK */
35#define MAX_COUNT 3
36
37#define SLEEP_DURATION_LOW 55
38#define SLEEP_DURATION_HI 65
39
40/* max. number of iterations after I2C NAK for 'long' commands
41 * we need this especially for sending TPM_READY, since the cleanup after the
42 * transtion to the ready state may take some time, but it is unpredictable
43 * how long it will take.
44 */
45#define MAX_COUNT_LONG 50
46
47#define SLEEP_DURATION_LONG_LOW 200
48#define SLEEP_DURATION_LONG_HI 220
49
50/* After sending TPM_READY to 'reset' the TPM we have to sleep even longer */
51#define SLEEP_DURATION_RESET_LOW 2400
52#define SLEEP_DURATION_RESET_HI 2600
53
54/* we want to use usleep_range instead of msleep for the 5ms TPM_TIMEOUT */
55#define TPM_TIMEOUT_US_LOW (TPM_TIMEOUT * 1000)
56#define TPM_TIMEOUT_US_HI (TPM_TIMEOUT_US_LOW + 2000)
57
58/* expected value for DIDVID register */
59#define TPM_TIS_I2C_DID_VID 0x000b15d1L
60
61/* Structure to store I2C TPM specific stuff */
62struct tpm_inf_dev {
63 struct i2c_client *client;
64 u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
65 struct tpm_chip *chip;
66};
67
68static struct tpm_inf_dev tpm_dev;
69static struct i2c_driver tpm_tis_i2c_driver;
70
71/*
72 * iic_tpm_read() - read from TPM register
73 * @addr: register address to read from
74 * @buffer: provided by caller
75 * @len: number of bytes to read
76 *
77 * Read len bytes from TPM register and put them into
78 * buffer (little-endian format, i.e. first byte is put into buffer[0]).
79 *
80 * NOTE: TPM is big-endian for multi-byte values. Multi-byte
81 * values have to be swapped.
82 *
83 * NOTE: We can't unfortunately use the combined read/write functions
84 * provided by the i2c core as the TPM currently does not support the
85 * repeated start condition and due to it's special requirements.
86 * The i2c_smbus* functions do not work for this chip.
87 *
88 * Return -EIO on error, 0 on success.
89 */
90static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
91{
92
93 struct i2c_msg msg1 = { tpm_dev.client->addr, 0, 1, &addr };
94 struct i2c_msg msg2 = { tpm_dev.client->addr, I2C_M_RD, len, buffer };
95
96 int rc;
97 int count;
98
99 /* Lock the adapter for the duration of the whole sequence. */
100 if (!tpm_dev.client->adapter->algo->master_xfer)
101 return -EOPNOTSUPP;
102 i2c_lock_adapter(tpm_dev.client->adapter);
103
104 for (count = 0; count < MAX_COUNT; count++) {
105 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
106 if (rc > 0)
107 break; /* break here to skip sleep */
108
109 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
110 }
111
112 if (rc <= 0)
113 goto out;
114
115 /* After the TPM has successfully received the register address it needs
116 * some time, thus we're sleeping here again, before retrieving the data
117 */
118 for (count = 0; count < MAX_COUNT; count++) {
119 usleep_range(SLEEP_DURATION_LOW, SLEEP_DURATION_HI);
120 rc = __i2c_transfer(tpm_dev.client->adapter, &msg2, 1);
121 if (rc > 0)
122 break;
123
124 }
125
126out:
127 i2c_unlock_adapter(tpm_dev.client->adapter);
128 if (rc <= 0)
129 return -EIO;
130
131 return 0;
132}
133
134static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
135 unsigned int sleep_low,
136 unsigned int sleep_hi, u8 max_count)
137{
138 int rc = -EIO;
139 int count;
140
141 struct i2c_msg msg1 = { tpm_dev.client->addr, 0, len + 1, tpm_dev.buf };
142
143 if (len > TPM_BUFSIZE)
144 return -EINVAL;
145
146 if (!tpm_dev.client->adapter->algo->master_xfer)
147 return -EOPNOTSUPP;
148 i2c_lock_adapter(tpm_dev.client->adapter);
149
150 /* prepend the 'register address' to the buffer */
151 tpm_dev.buf[0] = addr;
152 memcpy(&(tpm_dev.buf[1]), buffer, len);
153
154 /*
155 * NOTE: We have to use these special mechanisms here and unfortunately
156 * cannot rely on the standard behavior of i2c_transfer.
157 */
158 for (count = 0; count < max_count; count++) {
159 rc = __i2c_transfer(tpm_dev.client->adapter, &msg1, 1);
160 if (rc > 0)
161 break;
162
163 usleep_range(sleep_low, sleep_hi);
164 }
165
166 i2c_unlock_adapter(tpm_dev.client->adapter);
167 if (rc <= 0)
168 return -EIO;
169
170 return 0;
171}
172
173/*
174 * iic_tpm_write() - write to TPM register
175 * @addr: register address to write to
176 * @buffer: containing data to be written
177 * @len: number of bytes to write
178 *
179 * Write len bytes from provided buffer to TPM register (little
180 * endian format, i.e. buffer[0] is written as first byte).
181 *
182 * NOTE: TPM is big-endian for multi-byte values. Multi-byte
183 * values have to be swapped.
184 *
185 * NOTE: use this function instead of the iic_tpm_write_generic function.
186 *
187 * Return -EIO on error, 0 on success
188 */
189static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
190{
191 return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LOW,
192 SLEEP_DURATION_HI, MAX_COUNT);
193}
194
195/*
196 * This function is needed especially for the cleanup situation after
197 * sending TPM_READY
198 * */
199static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
200{
201 return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG_LOW,
202 SLEEP_DURATION_LONG_HI, MAX_COUNT_LONG);
203}
204
205enum tis_access {
206 TPM_ACCESS_VALID = 0x80,
207 TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
208 TPM_ACCESS_REQUEST_PENDING = 0x04,
209 TPM_ACCESS_REQUEST_USE = 0x02,
210};
211
212enum tis_status {
213 TPM_STS_VALID = 0x80,
214 TPM_STS_COMMAND_READY = 0x40,
215 TPM_STS_GO = 0x20,
216 TPM_STS_DATA_AVAIL = 0x10,
217 TPM_STS_DATA_EXPECT = 0x08,
218};
219
220enum tis_defaults {
221 TIS_SHORT_TIMEOUT = 750, /* ms */
222 TIS_LONG_TIMEOUT = 2000, /* 2 sec */
223};
224
225#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
226#define TPM_STS(l) (0x0001 | ((l) << 4))
227#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
228#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
229
230static int check_locality(struct tpm_chip *chip, int loc)
231{
232 u8 buf;
233 int rc;
234
235 rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
236 if (rc < 0)
237 return rc;
238
239 if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
240 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
241 chip->vendor.locality = loc;
242 return loc;
243 }
244
245 return -EIO;
246}
247
248/* implementation similar to tpm_tis */
249static void release_locality(struct tpm_chip *chip, int loc, int force)
250{
251 u8 buf;
252 if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
253 return;
254
255 if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
256 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
257 buf = TPM_ACCESS_ACTIVE_LOCALITY;
258 iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
259 }
260}
261
262static int request_locality(struct tpm_chip *chip, int loc)
263{
264 unsigned long stop;
265 u8 buf = TPM_ACCESS_REQUEST_USE;
266
267 if (check_locality(chip, loc) >= 0)
268 return loc;
269
270 iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
271
272 /* wait for burstcount */
273 stop = jiffies + chip->vendor.timeout_a;
274 do {
275 if (check_locality(chip, loc) >= 0)
276 return loc;
277 usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
278 } while (time_before(jiffies, stop));
279
280 return -ETIME;
281}
282
283static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
284{
285 /* NOTE: since I2C read may fail, return 0 in this case --> time-out */
286 u8 buf;
287 if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
288 return 0;
289 else
290 return buf;
291}
292
293static void tpm_tis_i2c_ready(struct tpm_chip *chip)
294{
295 /* this causes the current command to be aborted */
296 u8 buf = TPM_STS_COMMAND_READY;
297 iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
298}
299
300static ssize_t get_burstcount(struct tpm_chip *chip)
301{
302 unsigned long stop;
303 ssize_t burstcnt;
304 u8 buf[3];
305
306 /* wait for burstcount */
307 /* which timeout value, spec has 2 answers (c & d) */
308 stop = jiffies + chip->vendor.timeout_d;
309 do {
310 /* Note: STS is little endian */
311 if (iic_tpm_read(TPM_STS(chip->vendor.locality)+1, buf, 3) < 0)
312 burstcnt = 0;
313 else
314 burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
315
316 if (burstcnt)
317 return burstcnt;
318
319 usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
320 } while (time_before(jiffies, stop));
321 return -EBUSY;
322}
323
324static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
325 int *status)
326{
327 unsigned long stop;
328
329 /* check current status */
330 *status = tpm_tis_i2c_status(chip);
331 if ((*status & mask) == mask)
332 return 0;
333
334 stop = jiffies + timeout;
335 do {
336 /* since we just checked the status, give the TPM some time */
337 usleep_range(TPM_TIMEOUT_US_LOW, TPM_TIMEOUT_US_HI);
338 *status = tpm_tis_i2c_status(chip);
339 if ((*status & mask) == mask)
340 return 0;
341
342 } while (time_before(jiffies, stop));
343
344 return -ETIME;
345}
346
347static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
348{
349 size_t size = 0;
350 ssize_t burstcnt;
351 u8 retries = 0;
352 int rc;
353
354 while (size < count) {
355 burstcnt = get_burstcount(chip);
356
357 /* burstcnt < 0 = TPM is busy */
358 if (burstcnt < 0)
359 return burstcnt;
360
361 /* limit received data to max. left */
362 if (burstcnt > (count - size))
363 burstcnt = count - size;
364
365 rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
366 &(buf[size]), burstcnt);
367 if (rc == 0)
368 size += burstcnt;
369 else if (rc < 0)
370 retries++;
371
372 /* avoid endless loop in case of broken HW */
373 if (retries > MAX_COUNT_LONG)
374 return -EIO;
375
376 }
377 return size;
378}
379
380static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
381{
382 int size = 0;
383 int expected, status;
384
385 if (count < TPM_HEADER_SIZE) {
386 size = -EIO;
387 goto out;
388 }
389
390 /* read first 10 bytes, including tag, paramsize, and result */
391 size = recv_data(chip, buf, TPM_HEADER_SIZE);
392 if (size < TPM_HEADER_SIZE) {
393 dev_err(chip->dev, "Unable to read header\n");
394 goto out;
395 }
396
397 expected = be32_to_cpu(*(__be32 *)(buf + 2));
398 if ((size_t) expected > count) {
399 size = -EIO;
400 goto out;
401 }
402
403 size += recv_data(chip, &buf[TPM_HEADER_SIZE],
404 expected - TPM_HEADER_SIZE);
405 if (size < expected) {
406 dev_err(chip->dev, "Unable to read remainder of result\n");
407 size = -ETIME;
408 goto out;
409 }
410
411 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
412 if (status & TPM_STS_DATA_AVAIL) { /* retry? */
413 dev_err(chip->dev, "Error left over data\n");
414 size = -EIO;
415 goto out;
416 }
417
418out:
419 tpm_tis_i2c_ready(chip);
420 /* The TPM needs some time to clean up here,
421 * so we sleep rather than keeping the bus busy
422 */
423 usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI);
424 release_locality(chip, chip->vendor.locality, 0);
425 return size;
426}
427
428static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
429{
430 int rc, status;
431 ssize_t burstcnt;
432 size_t count = 0;
433 u8 retries = 0;
434 u8 sts = TPM_STS_GO;
435
436 if (len > TPM_BUFSIZE)
437 return -E2BIG; /* command is too long for our tpm, sorry */
438
439 if (request_locality(chip, 0) < 0)
440 return -EBUSY;
441
442 status = tpm_tis_i2c_status(chip);
443 if ((status & TPM_STS_COMMAND_READY) == 0) {
444 tpm_tis_i2c_ready(chip);
445 if (wait_for_stat
446 (chip, TPM_STS_COMMAND_READY,
447 chip->vendor.timeout_b, &status) < 0) {
448 rc = -ETIME;
449 goto out_err;
450 }
451 }
452
453 while (count < len - 1) {
454 burstcnt = get_burstcount(chip);
455
456 /* burstcnt < 0 = TPM is busy */
457 if (burstcnt < 0)
458 return burstcnt;
459
460 if (burstcnt > (len - 1 - count))
461 burstcnt = len - 1 - count;
462
463 rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
464 &(buf[count]), burstcnt);
465 if (rc == 0)
466 count += burstcnt;
467 else if (rc < 0)
468 retries++;
469
470 /* avoid endless loop in case of broken HW */
471 if (retries > MAX_COUNT_LONG) {
472 rc = -EIO;
473 goto out_err;
474 }
475
476 wait_for_stat(chip, TPM_STS_VALID,
477 chip->vendor.timeout_c, &status);
478
479 if ((status & TPM_STS_DATA_EXPECT) == 0) {
480 rc = -EIO;
481 goto out_err;
482 }
483
484 }
485
486 /* write last byte */
487 iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
488 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
489 if ((status & TPM_STS_DATA_EXPECT) != 0) {
490 rc = -EIO;
491 goto out_err;
492 }
493
494 /* go and do it */
495 iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
496
497 return len;
498out_err:
499 tpm_tis_i2c_ready(chip);
500 /* The TPM needs some time to clean up here,
501 * so we sleep rather than keeping the bus busy
502 */
503 usleep_range(SLEEP_DURATION_RESET_LOW, SLEEP_DURATION_RESET_HI);
504 release_locality(chip, chip->vendor.locality, 0);
505 return rc;
506}
507
508static const struct file_operations tis_ops = {
509 .owner = THIS_MODULE,
510 .llseek = no_llseek,
511 .open = tpm_open,
512 .read = tpm_read,
513 .write = tpm_write,
514 .release = tpm_release,
515};
516
517static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
518static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
519static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
520static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
521static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
522static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, NULL);
523static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
524static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
525static DEVICE_ATTR(durations, S_IRUGO, tpm_show_durations, NULL);
526static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
527
528static struct attribute *tis_attrs[] = {
529 &dev_attr_pubek.attr,
530 &dev_attr_pcrs.attr,
531 &dev_attr_enabled.attr,
532 &dev_attr_active.attr,
533 &dev_attr_owned.attr,
534 &dev_attr_temp_deactivated.attr,
535 &dev_attr_caps.attr,
536 &dev_attr_cancel.attr,
537 &dev_attr_durations.attr,
538 &dev_attr_timeouts.attr,
539 NULL,
540};
541
542static struct attribute_group tis_attr_grp = {
543 .attrs = tis_attrs
544};
545
546static struct tpm_vendor_specific tpm_tis_i2c = {
547 .status = tpm_tis_i2c_status,
548 .recv = tpm_tis_i2c_recv,
549 .send = tpm_tis_i2c_send,
550 .cancel = tpm_tis_i2c_ready,
551 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
552 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
553 .req_canceled = TPM_STS_COMMAND_READY,
554 .attr_group = &tis_attr_grp,
555 .miscdev.fops = &tis_ops,
556};
557
558static int __devinit tpm_tis_i2c_init(struct device *dev)
559{
560 u32 vendor;
561 int rc = 0;
562 struct tpm_chip *chip;
563
564 chip = tpm_register_hardware(dev, &tpm_tis_i2c);
565 if (!chip) {
566 rc = -ENODEV;
567 goto out_err;
568 }
569
570 /* Disable interrupts */
571 chip->vendor.irq = 0;
572
573 /* Default timeouts */
574 chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
575 chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
576 chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
577 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
578
579 if (request_locality(chip, 0) != 0) {
580 rc = -ENODEV;
581 goto out_vendor;
582 }
583
584 /* read four bytes from DID_VID register */
585 if (iic_tpm_read(TPM_DID_VID(0), (u8 *)&vendor, 4) < 0) {
586 rc = -EIO;
587 goto out_release;
588 }
589
590 /* create DID_VID register value, after swapping to little-endian */
591 vendor = be32_to_cpu((__be32) vendor);
592
593 if (vendor != TPM_TIS_I2C_DID_VID) {
594 rc = -ENODEV;
595 goto out_release;
596 }
597
598 dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16);
599
600 INIT_LIST_HEAD(&chip->vendor.list);
601 tpm_dev.chip = chip;
602
603 tpm_get_timeouts(chip);
604 tpm_do_selftest(chip);
605
606 return 0;
607
608out_release:
609 release_locality(chip, chip->vendor.locality, 1);
610
611out_vendor:
612 /* close file handles */
613 tpm_dev_vendor_release(chip);
614
615 /* remove hardware */
616 tpm_remove_hardware(chip->dev);
617
618 /* reset these pointers, otherwise we oops */
619 chip->dev->release = NULL;
620 chip->release = NULL;
621 tpm_dev.client = NULL;
622 dev_set_drvdata(chip->dev, chip);
623out_err:
624 return rc;
625}
626
627static const struct i2c_device_id tpm_tis_i2c_table[] = {
628 {"tpm_i2c_infineon", 0},
629 {},
630};
631
632MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table);
633static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume);
634
635static int __devinit tpm_tis_i2c_probe(struct i2c_client *client,
636 const struct i2c_device_id *id)
637{
638 int rc;
639 if (tpm_dev.client != NULL)
640 return -EBUSY; /* We only support one client */
641
642 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
643 dev_err(&client->dev,
644 "no algorithms associated to the i2c bus\n");
645 return -ENODEV;
646 }
647
648 client->driver = &tpm_tis_i2c_driver;
649 tpm_dev.client = client;
650 rc = tpm_tis_i2c_init(&client->dev);
651 if (rc != 0) {
652 client->driver = NULL;
653 tpm_dev.client = NULL;
654 rc = -ENODEV;
655 }
656 return rc;
657}
658
659static int __devexit tpm_tis_i2c_remove(struct i2c_client *client)
660{
661 struct tpm_chip *chip = tpm_dev.chip;
662 release_locality(chip, chip->vendor.locality, 1);
663
664 /* close file handles */
665 tpm_dev_vendor_release(chip);
666
667 /* remove hardware */
668 tpm_remove_hardware(chip->dev);
669
670 /* reset these pointers, otherwise we oops */
671 chip->dev->release = NULL;
672 chip->release = NULL;
673 tpm_dev.client = NULL;
674 dev_set_drvdata(chip->dev, chip);
675
676 return 0;
677}
678
679static struct i2c_driver tpm_tis_i2c_driver = {
680
681 .id_table = tpm_tis_i2c_table,
682 .probe = tpm_tis_i2c_probe,
683 .remove = tpm_tis_i2c_remove,
684 .driver = {
685 .name = "tpm_i2c_infineon",
686 .owner = THIS_MODULE,
687 .pm = &tpm_tis_i2c_ops,
688 },
689};
690
691module_i2c_driver(tpm_tis_i2c_driver);
692MODULE_AUTHOR("Peter Huewe <peter.huewe@infineon.com>");
693MODULE_DESCRIPTION("TPM TIS I2C Infineon Driver");
694MODULE_VERSION("2.1.5");
695MODULE_LICENSE("GPL");