aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-04-29 02:15:57 -0400
committerPaul Mackerras <paulus@samba.org>2006-04-29 02:15:57 -0400
commit29f147d746326e4db5fe350c70373081d61a2965 (patch)
tree04c065ace8c62953441bc22079b93449b996f283 /drivers/char
parent916a3d5729c8b710d56acf579f3fdb4de7c03e77 (diff)
parent6fb8f3acbe833586eb32598d1f844eb9f77c4fba (diff)
Merge branch 'merge'
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/drmP.h1
-rw-r--r--drivers/char/drm/drm_agpsupport.c2
-rw-r--r--drivers/char/drm/drm_bufs.c5
-rw-r--r--drivers/char/drm/drm_stub.c2
-rw-r--r--drivers/char/drm/r300_cmdbuf.c2
-rw-r--r--drivers/char/mem.c14
-rw-r--r--drivers/char/snsc.c3
-rw-r--r--drivers/char/tpm/Kconfig11
-rw-r--r--drivers/char/tpm/Makefile1
-rw-r--r--drivers/char/tpm/tpm.c786
-rw-r--r--drivers/char/tpm/tpm.h37
-rw-r--r--drivers/char/tpm/tpm_atmel.c58
-rw-r--r--drivers/char/tpm/tpm_atmel.h25
-rw-r--r--drivers/char/tpm/tpm_bios.c52
-rw-r--r--drivers/char/tpm/tpm_infineon.c61
-rw-r--r--drivers/char/tpm/tpm_nsc.c49
-rw-r--r--drivers/char/tpm/tpm_tis.c669
17 files changed, 1546 insertions, 232 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index e1aadae0062..cb76e5ca9a2 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -889,7 +889,6 @@ extern int drm_lock_free(drm_device_t * dev,
889 /* Buffer management support (drm_bufs.h) */ 889 /* Buffer management support (drm_bufs.h) */
890extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); 890extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request);
891extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); 891extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request);
892extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request);
893extern int drm_addmap(drm_device_t * dev, unsigned int offset, 892extern int drm_addmap(drm_device_t * dev, unsigned int offset,
894 unsigned int size, drm_map_type_t type, 893 unsigned int size, drm_map_type_t type,
895 drm_map_flags_t flags, drm_local_map_t ** map_ptr); 894 drm_map_flags_t flags, drm_local_map_t ** map_ptr);
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
index fabc930c67a..40bfd9b01e3 100644
--- a/drivers/char/drm/drm_agpsupport.c
+++ b/drivers/char/drm/drm_agpsupport.c
@@ -503,8 +503,6 @@ int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start)
503 return agp_bind_memory(handle, start); 503 return agp_bind_memory(handle, start);
504} 504}
505 505
506EXPORT_SYMBOL(drm_agp_bind_memory);
507
508/** Calls agp_unbind_memory() */ 506/** Calls agp_unbind_memory() */
509int drm_agp_unbind_memory(DRM_AGP_MEM * handle) 507int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
510{ 508{
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 8a9cf12e618..006b06d2972 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -386,7 +386,6 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
386 386
387 return 0; 387 return 0;
388} 388}
389EXPORT_SYMBOL(drm_rmmap_locked);
390 389
391int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) 390int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
392{ 391{
@@ -398,7 +397,6 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
398 397
399 return ret; 398 return ret;
400} 399}
401EXPORT_SYMBOL(drm_rmmap);
402 400
403/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on 401/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
404 * the last close of the device, and this is necessary for cleanup when things 402 * the last close of the device, and this is necessary for cleanup when things
@@ -1053,7 +1051,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
1053 return 0; 1051 return 0;
1054} 1052}
1055 1053
1056int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) 1054static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
1057{ 1055{
1058 drm_device_dma_t *dma = dev->dma; 1056 drm_device_dma_t *dma = dev->dma;
1059 drm_buf_entry_t *entry; 1057 drm_buf_entry_t *entry;
@@ -1212,7 +1210,6 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request)
1212 atomic_dec(&dev->buf_alloc); 1210 atomic_dec(&dev->buf_alloc);
1213 return 0; 1211 return 0;
1214} 1212}
1215EXPORT_SYMBOL(drm_addbufs_fb);
1216 1213
1217 1214
1218/** 1215/**
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 68073e14fde..9a842a36bb2 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -229,8 +229,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
229 return ret; 229 return ret;
230} 230}
231 231
232EXPORT_SYMBOL(drm_get_dev);
233
234/** 232/**
235 * Put a device minor number. 233 * Put a device minor number.
236 * 234 *
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
index b108c7f913b..26bdf2ca59d 100644
--- a/drivers/char/drm/r300_cmdbuf.c
+++ b/drivers/char/drm/r300_cmdbuf.c
@@ -723,7 +723,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
723 723
724 dev_priv->scratch_ages[header.scratch.reg]++; 724 dev_priv->scratch_ages[header.scratch.reg]++;
725 725
726 ref_age_base = *(u32 **)cmdbuf->buf; 726 ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf);
727 727
728 cmdbuf->buf += sizeof(u64); 728 cmdbuf->buf += sizeof(u64);
729 cmdbuf->bufsz -= sizeof(u64); 729 cmdbuf->bufsz -= sizeof(u64);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 66719f9d294..1fa9fa157c1 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -27,6 +27,7 @@
27#include <linux/crash_dump.h> 27#include <linux/crash_dump.h>
28#include <linux/backing-dev.h> 28#include <linux/backing-dev.h>
29#include <linux/bootmem.h> 29#include <linux/bootmem.h>
30#include <linux/pipe_fs_i.h>
30 31
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
32#include <asm/io.h> 33#include <asm/io.h>
@@ -578,6 +579,18 @@ static ssize_t write_null(struct file * file, const char __user * buf,
578 return count; 579 return count;
579} 580}
580 581
582static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
583 struct splice_desc *sd)
584{
585 return sd->len;
586}
587
588static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
589 loff_t *ppos, size_t len, unsigned int flags)
590{
591 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
592}
593
581#ifdef CONFIG_MMU 594#ifdef CONFIG_MMU
582/* 595/*
583 * For fun, we are using the MMU for this. 596 * For fun, we are using the MMU for this.
@@ -785,6 +798,7 @@ static struct file_operations null_fops = {
785 .llseek = null_lseek, 798 .llseek = null_lseek,
786 .read = read_null, 799 .read = read_null,
787 .write = write_null, 800 .write = write_null,
801 .splice_write = splice_write_null,
788}; 802};
789 803
790#if defined(CONFIG_ISA) || !defined(__mc68000__) 804#if defined(CONFIG_ISA) || !defined(__mc68000__)
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index b543821d8cb..56c8243cdb7 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -390,7 +390,8 @@ scdrv_init(void)
390 format_module_id(devnamep, geo_module(geoid), 390 format_module_id(devnamep, geo_module(geoid),
391 MODULE_FORMAT_BRIEF); 391 MODULE_FORMAT_BRIEF);
392 devnamep = devname + strlen(devname); 392 devnamep = devname + strlen(devname);
393 sprintf(devnamep, "#%d", geo_slab(geoid)); 393 sprintf(devnamep, "^%d#%d", geo_slot(geoid),
394 geo_slab(geoid));
394 395
395 /* allocate sysctl device data */ 396 /* allocate sysctl device data */
396 scd = kzalloc(sizeof (struct sysctl_data_s), 397 scd = kzalloc(sizeof (struct sysctl_data_s),
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index a6873bf89ff..1efde3b2761 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 ba4582d160f..ea3a1e02a82 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 5a3870477ef..6889e7db3af 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -32,12 +32,291 @@ enum tpm_const {
32 TPM_MINOR = 224, /* officially assigned */ 32 TPM_MINOR = 224, /* officially assigned */
33 TPM_BUFSIZE = 2048, 33 TPM_BUFSIZE = 2048,
34 TPM_NUM_DEVICES = 256, 34 TPM_NUM_DEVICES = 256,
35 TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
36}; 35};
37 36
37enum tpm_duration {
38 TPM_SHORT = 0,
39 TPM_MEDIUM = 1,
40 TPM_LONG = 2,
41 TPM_UNDEFINED,
42};
43
44#define TPM_MAX_ORDINAL 243
45#define TPM_MAX_PROTECTED_ORDINAL 12
46#define TPM_PROTECTED_ORDINAL_MASK 0xFF
47
38static LIST_HEAD(tpm_chip_list); 48static LIST_HEAD(tpm_chip_list);
39static DEFINE_SPINLOCK(driver_lock); 49static DEFINE_SPINLOCK(driver_lock);
40static int dev_mask[TPM_NUM_MASK_ENTRIES]; 50static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
51
52/*
53 * Array with one entry per ordinal defining the maximum amount
54 * of time the chip could take to return the result. The ordinal
55 * designation of short, medium or long is defined in a table in
56 * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
57 * values of the SHORT, MEDIUM, and LONG durations are retrieved
58 * from the chip during initialization with a call to tpm_get_timeouts.
59 */
60static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
61 TPM_UNDEFINED, /* 0 */
62 TPM_UNDEFINED,
63 TPM_UNDEFINED,
64 TPM_UNDEFINED,
65 TPM_UNDEFINED,
66 TPM_UNDEFINED, /* 5 */
67 TPM_UNDEFINED,
68 TPM_UNDEFINED,
69 TPM_UNDEFINED,
70 TPM_UNDEFINED,
71 TPM_SHORT, /* 10 */
72 TPM_SHORT,
73};
74
75static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
76 TPM_UNDEFINED, /* 0 */
77 TPM_UNDEFINED,
78 TPM_UNDEFINED,
79 TPM_UNDEFINED,
80 TPM_UNDEFINED,
81 TPM_UNDEFINED, /* 5 */
82 TPM_UNDEFINED,
83 TPM_UNDEFINED,
84 TPM_UNDEFINED,
85 TPM_UNDEFINED,
86 TPM_SHORT, /* 10 */
87 TPM_SHORT,
88 TPM_MEDIUM,
89 TPM_LONG,
90 TPM_LONG,
91 TPM_MEDIUM, /* 15 */
92 TPM_SHORT,
93 TPM_SHORT,
94 TPM_MEDIUM,
95 TPM_LONG,
96 TPM_SHORT, /* 20 */
97 TPM_SHORT,
98 TPM_MEDIUM,
99 TPM_MEDIUM,
100 TPM_MEDIUM,
101 TPM_SHORT, /* 25 */
102 TPM_SHORT,
103 TPM_MEDIUM,
104 TPM_SHORT,
105 TPM_SHORT,
106 TPM_MEDIUM, /* 30 */
107 TPM_LONG,
108 TPM_MEDIUM,
109 TPM_SHORT,
110 TPM_SHORT,
111 TPM_SHORT, /* 35 */
112 TPM_MEDIUM,
113 TPM_MEDIUM,
114 TPM_UNDEFINED,
115 TPM_UNDEFINED,
116 TPM_MEDIUM, /* 40 */
117 TPM_LONG,
118 TPM_MEDIUM,
119 TPM_SHORT,
120 TPM_SHORT,
121 TPM_SHORT, /* 45 */
122 TPM_SHORT,
123 TPM_SHORT,
124 TPM_SHORT,
125 TPM_LONG,
126 TPM_MEDIUM, /* 50 */
127 TPM_MEDIUM,
128 TPM_UNDEFINED,
129 TPM_UNDEFINED,
130 TPM_UNDEFINED,
131 TPM_UNDEFINED, /* 55 */
132 TPM_UNDEFINED,
133 TPM_UNDEFINED,
134 TPM_UNDEFINED,
135 TPM_UNDEFINED,
136 TPM_MEDIUM, /* 60 */
137 TPM_MEDIUM,
138 TPM_MEDIUM,
139 TPM_SHORT,
140 TPM_SHORT,
141 TPM_MEDIUM, /* 65 */
142 TPM_UNDEFINED,
143 TPM_UNDEFINED,
144 TPM_UNDEFINED,
145 TPM_UNDEFINED,
146 TPM_SHORT, /* 70 */
147 TPM_SHORT,
148 TPM_UNDEFINED,
149 TPM_UNDEFINED,
150 TPM_UNDEFINED,
151 TPM_UNDEFINED, /* 75 */
152 TPM_UNDEFINED,
153 TPM_UNDEFINED,
154 TPM_UNDEFINED,
155 TPM_UNDEFINED,
156 TPM_LONG, /* 80 */
157 TPM_UNDEFINED,
158 TPM_MEDIUM,
159 TPM_LONG,
160 TPM_SHORT,
161 TPM_UNDEFINED, /* 85 */
162 TPM_UNDEFINED,
163 TPM_UNDEFINED,
164 TPM_UNDEFINED,
165 TPM_UNDEFINED,
166 TPM_SHORT, /* 90 */
167 TPM_SHORT,
168 TPM_SHORT,
169 TPM_SHORT,
170 TPM_SHORT,
171 TPM_UNDEFINED, /* 95 */
172 TPM_UNDEFINED,
173 TPM_UNDEFINED,
174 TPM_UNDEFINED,
175 TPM_UNDEFINED,
176 TPM_MEDIUM, /* 100 */
177 TPM_SHORT,
178 TPM_SHORT,
179 TPM_UNDEFINED,
180 TPM_UNDEFINED,
181 TPM_UNDEFINED, /* 105 */
182 TPM_UNDEFINED,
183 TPM_UNDEFINED,
184 TPM_UNDEFINED,
185 TPM_UNDEFINED,
186 TPM_SHORT, /* 110 */
187 TPM_SHORT,
188 TPM_SHORT,
189 TPM_SHORT,
190 TPM_SHORT,
191 TPM_SHORT, /* 115 */
192 TPM_SHORT,
193 TPM_SHORT,
194 TPM_UNDEFINED,
195 TPM_UNDEFINED,
196 TPM_LONG, /* 120 */
197 TPM_LONG,
198 TPM_MEDIUM,
199 TPM_UNDEFINED,
200 TPM_SHORT,
201 TPM_SHORT, /* 125 */
202 TPM_SHORT,
203 TPM_LONG,
204 TPM_SHORT,
205 TPM_SHORT,
206 TPM_SHORT, /* 130 */
207 TPM_MEDIUM,
208 TPM_UNDEFINED,
209 TPM_SHORT,
210 TPM_MEDIUM,
211 TPM_UNDEFINED, /* 135 */
212 TPM_UNDEFINED,
213 TPM_UNDEFINED,
214 TPM_UNDEFINED,
215 TPM_UNDEFINED,
216 TPM_SHORT, /* 140 */
217 TPM_SHORT,
218 TPM_UNDEFINED,
219 TPM_UNDEFINED,
220 TPM_UNDEFINED,
221 TPM_UNDEFINED, /* 145 */
222 TPM_UNDEFINED,
223 TPM_UNDEFINED,
224 TPM_UNDEFINED,
225 TPM_UNDEFINED,
226 TPM_SHORT, /* 150 */
227 TPM_MEDIUM,
228 TPM_MEDIUM,
229 TPM_SHORT,
230 TPM_SHORT,
231 TPM_UNDEFINED, /* 155 */
232 TPM_UNDEFINED,
233 TPM_UNDEFINED,
234 TPM_UNDEFINED,
235 TPM_UNDEFINED,
236 TPM_SHORT, /* 160 */
237 TPM_SHORT,
238 TPM_SHORT,
239 TPM_SHORT,
240 TPM_UNDEFINED,
241 TPM_UNDEFINED, /* 165 */
242 TPM_UNDEFINED,
243 TPM_UNDEFINED,
244 TPM_UNDEFINED,
245 TPM_UNDEFINED,
246 TPM_LONG, /* 170 */
247 TPM_UNDEFINED,
248 TPM_UNDEFINED,
249 TPM_UNDEFINED,
250 TPM_UNDEFINED,
251 TPM_UNDEFINED, /* 175 */
252 TPM_UNDEFINED,
253 TPM_UNDEFINED,
254 TPM_UNDEFINED,
255 TPM_UNDEFINED,
256 TPM_MEDIUM, /* 180 */
257 TPM_SHORT,
258 TPM_MEDIUM,
259 TPM_MEDIUM,
260 TPM_MEDIUM,
261 TPM_MEDIUM, /* 185 */
262 TPM_SHORT,
263 TPM_UNDEFINED,
264 TPM_UNDEFINED,
265 TPM_UNDEFINED,
266 TPM_UNDEFINED, /* 190 */
267 TPM_UNDEFINED,
268 TPM_UNDEFINED,
269 TPM_UNDEFINED,
270 TPM_UNDEFINED,
271 TPM_UNDEFINED, /* 195 */
272 TPM_UNDEFINED,
273 TPM_UNDEFINED,
274 TPM_UNDEFINED,
275 TPM_UNDEFINED,
276 TPM_SHORT, /* 200 */
277 TPM_UNDEFINED,
278 TPM_UNDEFINED,
279 TPM_UNDEFINED,
280 TPM_SHORT,
281 TPM_SHORT, /* 205 */
282 TPM_SHORT,
283 TPM_SHORT,
284 TPM_SHORT,
285 TPM_SHORT,
286 TPM_MEDIUM, /* 210 */
287 TPM_UNDEFINED,
288 TPM_MEDIUM,
289 TPM_MEDIUM,
290 TPM_MEDIUM,
291 TPM_UNDEFINED, /* 215 */
292 TPM_MEDIUM,
293 TPM_UNDEFINED,
294 TPM_UNDEFINED,
295 TPM_SHORT,
296 TPM_SHORT, /* 220 */
297 TPM_SHORT,
298 TPM_SHORT,
299 TPM_SHORT,
300 TPM_SHORT,
301 TPM_UNDEFINED, /* 225 */
302 TPM_UNDEFINED,
303 TPM_UNDEFINED,
304 TPM_UNDEFINED,
305 TPM_UNDEFINED,
306 TPM_SHORT, /* 230 */
307 TPM_LONG,
308 TPM_MEDIUM,
309 TPM_UNDEFINED,
310 TPM_UNDEFINED,
311 TPM_UNDEFINED, /* 235 */
312 TPM_UNDEFINED,
313 TPM_UNDEFINED,
314 TPM_UNDEFINED,
315 TPM_UNDEFINED,
316 TPM_SHORT, /* 240 */
317 TPM_UNDEFINED,
318 TPM_MEDIUM,
319};
41 320
42static void user_reader_timeout(unsigned long ptr) 321static void user_reader_timeout(unsigned long ptr)
43{ 322{
@@ -46,7 +325,7 @@ static void user_reader_timeout(unsigned long ptr)
46 schedule_work(&chip->work); 325 schedule_work(&chip->work);
47} 326}
48 327
49static void timeout_work(void * ptr) 328static void timeout_work(void *ptr)
50{ 329{
51 struct tpm_chip *chip = ptr; 330 struct tpm_chip *chip = ptr;
52 331
@@ -57,17 +336,43 @@ static void timeout_work(void * ptr)
57} 336}
58 337
59/* 338/*
339 * Returns max number of jiffies to wait
340 */
341unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
342 u32 ordinal)
343{
344 int duration_idx = TPM_UNDEFINED;
345 int duration = 0;
346
347 if (ordinal < TPM_MAX_ORDINAL)
348 duration_idx = tpm_ordinal_duration[ordinal];
349 else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
350 TPM_MAX_PROTECTED_ORDINAL)
351 duration_idx =
352 tpm_protected_ordinal_duration[ordinal &
353 TPM_PROTECTED_ORDINAL_MASK];
354
355 if (duration_idx != TPM_UNDEFINED)
356 duration = chip->vendor.duration[duration_idx];
357 if (duration <= 0)
358 return 2 * 60 * HZ;
359 else
360 return duration;
361}
362EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
363
364/*
60 * Internal kernel interface to transmit TPM commands 365 * Internal kernel interface to transmit TPM commands
61 */ 366 */
62static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, 367static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
63 size_t bufsiz) 368 size_t bufsiz)
64{ 369{
65 ssize_t rc; 370 ssize_t rc;
66 u32 count; 371 u32 count, ordinal;
67 unsigned long stop; 372 unsigned long stop;
68 373
69 count = be32_to_cpu(*((__be32 *) (buf + 2))); 374 count = be32_to_cpu(*((__be32 *) (buf + 2)));
70 375 ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
71 if (count == 0) 376 if (count == 0)
72 return -ENODATA; 377 return -ENODATA;
73 if (count > bufsiz) { 378 if (count > bufsiz) {
@@ -78,21 +383,23 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
78 383
79 down(&chip->tpm_mutex); 384 down(&chip->tpm_mutex);
80 385
81 if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { 386 if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
82 dev_err(chip->dev, 387 dev_err(chip->dev,
83 "tpm_transmit: tpm_send: error %zd\n", rc); 388 "tpm_transmit: tpm_send: error %zd\n", rc);
84 goto out; 389 goto out;
85 } 390 }
86 391
87 stop = jiffies + 2 * 60 * HZ; 392 if (chip->vendor.irq)
393 goto out_recv;
394
395 stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
88 do { 396 do {
89 u8 status = chip->vendor->status(chip); 397 u8 status = chip->vendor.status(chip);
90 if ((status & chip->vendor->req_complete_mask) == 398 if ((status & chip->vendor.req_complete_mask) ==
91 chip->vendor->req_complete_val) { 399 chip->vendor.req_complete_val)
92 goto out_recv; 400 goto out_recv;
93 }
94 401
95 if ((status == chip->vendor->req_canceled)) { 402 if ((status == chip->vendor.req_canceled)) {
96 dev_err(chip->dev, "Operation Canceled\n"); 403 dev_err(chip->dev, "Operation Canceled\n");
97 rc = -ECANCELED; 404 rc = -ECANCELED;
98 goto out; 405 goto out;
@@ -102,14 +409,13 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
102 rmb(); 409 rmb();
103 } while (time_before(jiffies, stop)); 410 } while (time_before(jiffies, stop));
104 411
105 412 chip->vendor.cancel(chip);
106 chip->vendor->cancel(chip);
107 dev_err(chip->dev, "Operation Timed out\n"); 413 dev_err(chip->dev, "Operation Timed out\n");
108 rc = -ETIME; 414 rc = -ETIME;
109 goto out; 415 goto out;
110 416
111out_recv: 417out_recv:
112 rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); 418 rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
113 if (rc < 0) 419 if (rc < 0)
114 dev_err(chip->dev, 420 dev_err(chip->dev,
115 "tpm_transmit: tpm_recv: error %zd\n", rc); 421 "tpm_transmit: tpm_recv: error %zd\n", rc);
@@ -119,17 +425,247 @@ out:
119} 425}
120 426
121#define TPM_DIGEST_SIZE 20 427#define TPM_DIGEST_SIZE 20
122#define CAP_PCR_RESULT_SIZE 18 428#define TPM_ERROR_SIZE 10
123static const u8 cap_pcr[] = { 429#define TPM_RET_CODE_IDX 6
430#define TPM_GET_CAP_RET_SIZE_IDX 10
431#define TPM_GET_CAP_RET_UINT32_1_IDX 14
432#define TPM_GET_CAP_RET_UINT32_2_IDX 18
433#define TPM_GET_CAP_RET_UINT32_3_IDX 22
434#define TPM_GET_CAP_RET_UINT32_4_IDX 26
435#define TPM_GET_CAP_PERM_DISABLE_IDX 16
436#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
437#define TPM_GET_CAP_RET_BOOL_1_IDX 14
438#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
439
440#define TPM_CAP_IDX 13
441#define TPM_CAP_SUBCAP_IDX 21
442
443enum tpm_capabilities {
444 TPM_CAP_FLAG = 4,
445 TPM_CAP_PROP = 5,
446};
447
448enum tpm_sub_capabilities {
449 TPM_CAP_PROP_PCR = 0x1,
450 TPM_CAP_PROP_MANUFACTURER = 0x3,
451 TPM_CAP_FLAG_PERM = 0x8,
452 TPM_CAP_FLAG_VOL = 0x9,
453 TPM_CAP_PROP_OWNER = 0x11,
454 TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
455 TPM_CAP_PROP_TIS_DURATION = 0x20,
456};
457
458/*
459 * This is a semi generic GetCapability command for use
460 * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
461 * and their associated sub_capabilities.
462 */
463
464static const u8 tpm_cap[] = {
124 0, 193, /* TPM_TAG_RQU_COMMAND */ 465 0, 193, /* TPM_TAG_RQU_COMMAND */
125 0, 0, 0, 22, /* length */ 466 0, 0, 0, 22, /* length */
126 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 467 0, 0, 0, 101, /* TPM_ORD_GetCapability */
127 0, 0, 0, 5, 468 0, 0, 0, 0, /* TPM_CAP_<TYPE> */
128 0, 0, 0, 4, 469 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */
129 0, 0, 1, 1 470 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
130}; 471};
131 472
132#define READ_PCR_RESULT_SIZE 30 473static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
474 char *desc)
475{
476 int err;
477
478 len = tpm_transmit(chip, data, len);
479 if (len < 0)
480 return len;
481 if (len == TPM_ERROR_SIZE) {
482 err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
483 dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
484 return err;
485 }
486 return 0;
487}
488
489void tpm_gen_interrupt(struct tpm_chip *chip)
490{
491 u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
492 ssize_t rc;
493
494 memcpy(data, tpm_cap, sizeof(tpm_cap));
495 data[TPM_CAP_IDX] = TPM_CAP_PROP;
496 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
497
498 rc = transmit_cmd(chip, data, sizeof(data),
499 "attempting to determine the timeouts");
500}
501EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
502
503void tpm_get_timeouts(struct tpm_chip *chip)
504{
505 u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
506 ssize_t rc;
507 u32 timeout;
508
509 memcpy(data, tpm_cap, sizeof(tpm_cap));
510 data[TPM_CAP_IDX] = TPM_CAP_PROP;
511 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
512
513 rc = transmit_cmd(chip, data, sizeof(data),
514 "attempting to determine the timeouts");
515 if (rc)
516 goto duration;
517
518 if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
519 != 4 * sizeof(u32))
520 goto duration;
521
522 /* Don't overwrite default if value is 0 */
523 timeout =
524 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
525 if (timeout)
526 chip->vendor.timeout_a = msecs_to_jiffies(timeout);
527 timeout =
528 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
529 if (timeout)
530 chip->vendor.timeout_b = msecs_to_jiffies(timeout);
531 timeout =
532 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
533 if (timeout)
534 chip->vendor.timeout_c = msecs_to_jiffies(timeout);
535 timeout =
536 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
537 if (timeout)
538 chip->vendor.timeout_d = msecs_to_jiffies(timeout);
539
540duration:
541 memcpy(data, tpm_cap, sizeof(tpm_cap));
542 data[TPM_CAP_IDX] = TPM_CAP_PROP;
543 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
544
545 rc = transmit_cmd(chip, data, sizeof(data),
546 "attempting to determine the durations");
547 if (rc)
548 return;
549
550 if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
551 != 3 * sizeof(u32))
552 return;
553
554 chip->vendor.duration[TPM_SHORT] =
555 msecs_to_jiffies(be32_to_cpu
556 (*((__be32 *) (data +
557 TPM_GET_CAP_RET_UINT32_1_IDX))));
558 chip->vendor.duration[TPM_MEDIUM] =
559 msecs_to_jiffies(be32_to_cpu
560 (*((__be32 *) (data +
561 TPM_GET_CAP_RET_UINT32_2_IDX))));
562 chip->vendor.duration[TPM_LONG] =
563 msecs_to_jiffies(be32_to_cpu
564 (*((__be32 *) (data +
565 TPM_GET_CAP_RET_UINT32_3_IDX))));
566}
567EXPORT_SYMBOL_GPL(tpm_get_timeouts);
568
569void tpm_continue_selftest(struct tpm_chip *chip)
570{
571 u8 data[] = {
572 0, 193, /* TPM_TAG_RQU_COMMAND */
573 0, 0, 0, 10, /* length */
574 0, 0, 0, 83, /* TPM_ORD_GetCapability */
575 };
576
577 tpm_transmit(chip, data, sizeof(data));
578}
579EXPORT_SYMBOL_GPL(tpm_continue_selftest);
580
581ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
582 char *buf)
583{
584 u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
585 ssize_t rc;
586
587 struct tpm_chip *chip = dev_get_drvdata(dev);
588 if (chip == NULL)
589 return -ENODEV;
590
591 memcpy(data, tpm_cap, sizeof(tpm_cap));
592 data[TPM_CAP_IDX] = TPM_CAP_FLAG;
593 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
594
595 rc = transmit_cmd(chip, data, sizeof(data),
596 "attemtping to determine the permanent state");
597 if (rc)
598 return 0;
599 return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
600}
601EXPORT_SYMBOL_GPL(tpm_show_enabled);
602
603ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
604 char *buf)
605{
606 u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
607 ssize_t rc;
608
609 struct tpm_chip *chip = dev_get_drvdata(dev);
610 if (chip == NULL)
611 return -ENODEV;
612
613 memcpy(data, tpm_cap, sizeof(tpm_cap));
614 data[TPM_CAP_IDX] = TPM_CAP_FLAG;
615 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
616
617 rc = transmit_cmd(chip, data, sizeof(data),
618 "attemtping to determine the permanent state");
619 if (rc)
620 return 0;
621 return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
622}
623EXPORT_SYMBOL_GPL(tpm_show_active);
624
625ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
626 char *buf)
627{
628 u8 data[sizeof(tpm_cap)];
629 ssize_t rc;
630
631 struct tpm_chip *chip = dev_get_drvdata(dev);
632 if (chip == NULL)
633 return -ENODEV;
634
635 memcpy(data, tpm_cap, sizeof(tpm_cap));
636 data[TPM_CAP_IDX] = TPM_CAP_PROP;
637 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
638
639 rc = transmit_cmd(chip, data, sizeof(data),
640 "attempting to determine the owner state");
641 if (rc)
642 return 0;
643 return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
644}
645EXPORT_SYMBOL_GPL(tpm_show_owned);
646
647ssize_t tpm_show_temp_deactivated(struct device * dev,
648 struct device_attribute * attr, char *buf)
649{
650 u8 data[sizeof(tpm_cap)];
651 ssize_t rc;
652
653 struct tpm_chip *chip = dev_get_drvdata(dev);
654 if (chip == NULL)
655 return -ENODEV;
656
657 memcpy(data, tpm_cap, sizeof(tpm_cap));
658 data[TPM_CAP_IDX] = TPM_CAP_FLAG;
659 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
660
661 rc = transmit_cmd(chip, data, sizeof(data),
662 "attempting to determine the temporary state");
663 if (rc)
664 return 0;
665 return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
666}
667EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
668
133static const u8 pcrread[] = { 669static const u8 pcrread[] = {
134 0, 193, /* TPM_TAG_RQU_COMMAND */ 670 0, 193, /* TPM_TAG_RQU_COMMAND */
135 0, 0, 0, 14, /* length */ 671 0, 0, 0, 14, /* length */
@@ -140,8 +676,8 @@ static const u8 pcrread[] = {
140ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, 676ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
141 char *buf) 677 char *buf)
142{ 678{
143 u8 data[READ_PCR_RESULT_SIZE]; 679 u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
144 ssize_t len; 680 ssize_t rc;
145 int i, j, num_pcrs; 681 int i, j, num_pcrs;
146 __be32 index; 682 __be32 index;
147 char *str = buf; 683 char *str = buf;
@@ -150,29 +686,24 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
150 if (chip == NULL) 686 if (chip == NULL)
151 return -ENODEV; 687 return -ENODEV;
152 688
153 memcpy(data, cap_pcr, sizeof(cap_pcr)); 689 memcpy(data, tpm_cap, sizeof(tpm_cap));
154 if ((len = tpm_transmit(chip, data, sizeof(data))) 690 data[TPM_CAP_IDX] = TPM_CAP_PROP;
155 < CAP_PCR_RESULT_SIZE) { 691 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
156 dev_dbg(chip->dev, "A TPM error (%d) occurred " 692
157 "attempting to determine the number of PCRS\n", 693 rc = transmit_cmd(chip, data, sizeof(data),
158 be32_to_cpu(*((__be32 *) (data + 6)))); 694 "attempting to determine the number of PCRS");
695 if (rc)
159 return 0; 696 return 0;
160 }
161 697
162 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); 698 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
163
164 for (i = 0; i < num_pcrs; i++) { 699 for (i = 0; i < num_pcrs; i++) {
165 memcpy(data, pcrread, sizeof(pcrread)); 700 memcpy(data, pcrread, sizeof(pcrread));
166 index = cpu_to_be32(i); 701 index = cpu_to_be32(i);
167 memcpy(data + 10, &index, 4); 702 memcpy(data + 10, &index, 4);
168 if ((len = tpm_transmit(chip, data, sizeof(data))) 703 rc = transmit_cmd(chip, data, sizeof(data),
169 < READ_PCR_RESULT_SIZE){ 704 "attempting to read a PCR");
170 dev_dbg(chip->dev, "A TPM error (%d) occurred" 705 if (rc)
171 " attempting to read PCR %d of %d\n",
172 be32_to_cpu(*((__be32 *) (data + 6))),
173 i, num_pcrs);
174 goto out; 706 goto out;
175 }
176 str += sprintf(str, "PCR-%02d: ", i); 707 str += sprintf(str, "PCR-%02d: ", i);
177 for (j = 0; j < TPM_DIGEST_SIZE; j++) 708 for (j = 0; j < TPM_DIGEST_SIZE; j++)
178 str += sprintf(str, "%02X ", *(data + 10 + j)); 709 str += sprintf(str, "%02X ", *(data + 10 + j));
@@ -194,7 +725,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
194 char *buf) 725 char *buf)
195{ 726{
196 u8 *data; 727 u8 *data;
197 ssize_t len; 728 ssize_t err;
198 int i, rc; 729 int i, rc;
199 char *str = buf; 730 char *str = buf;
200 731
@@ -208,14 +739,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
208 739
209 memcpy(data, readpubek, sizeof(readpubek)); 740 memcpy(data, readpubek, sizeof(readpubek));
210 741
211 if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < 742 err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
212 READ_PUBEK_RESULT_SIZE) { 743 "attempting to read the PUBEK");
213 dev_dbg(chip->dev, "A TPM error (%d) occurred " 744 if (err)
214 "attempting to read the PUBEK\n",
215 be32_to_cpu(*((__be32 *) (data + 6))));
216 rc = 0;
217 goto out; 745 goto out;
218 }
219 746
220 /* 747 /*
221 ignore header 10 bytes 748 ignore header 10 bytes
@@ -245,67 +772,110 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
245 if ((i + 1) % 16 == 0) 772 if ((i + 1) % 16 == 0)
246 str += sprintf(str, "\n"); 773 str += sprintf(str, "\n");
247 } 774 }
248 rc = str - buf;
249out: 775out:
776 rc = str - buf;
250 kfree(data); 777 kfree(data);
251 return rc; 778 return rc;
252} 779}
253EXPORT_SYMBOL_GPL(tpm_show_pubek); 780EXPORT_SYMBOL_GPL(tpm_show_pubek);
254 781
255#define CAP_VER_RESULT_SIZE 18 782#define CAP_VERSION_1_1 6
783#define CAP_VERSION_1_2 0x1A
784#define CAP_VERSION_IDX 13
256static const u8 cap_version[] = { 785static const u8 cap_version[] = {
257 0, 193, /* TPM_TAG_RQU_COMMAND */ 786 0, 193, /* TPM_TAG_RQU_COMMAND */
258 0, 0, 0, 18, /* length */ 787 0, 0, 0, 18, /* length */
259 0, 0, 0, 101, /* TPM_ORD_GetCapability */ 788 0, 0, 0, 101, /* TPM_ORD_GetCapability */
260 0, 0, 0, 6, 789 0, 0, 0, 0,
261 0, 0, 0, 0 790 0, 0, 0, 0
262}; 791};
263 792
264#define CAP_MANUFACTURER_RESULT_SIZE 18
265static const u8 cap_manufacturer[] = {
266 0, 193, /* TPM_TAG_RQU_COMMAND */
267 0, 0, 0, 22, /* length */
268 0, 0, 0, 101, /* TPM_ORD_GetCapability */
269 0, 0, 0, 5,
270 0, 0, 0, 4,
271 0, 0, 1, 3
272};
273
274ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, 793ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
275 char *buf) 794 char *buf)
276{ 795{
277 u8 data[sizeof(cap_manufacturer)]; 796 u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
278 ssize_t len; 797 ssize_t rc;
279 char *str = buf; 798 char *str = buf;
280 799
281 struct tpm_chip *chip = dev_get_drvdata(dev); 800 struct tpm_chip *chip = dev_get_drvdata(dev);
282 if (chip == NULL) 801 if (chip == NULL)
283 return -ENODEV; 802 return -ENODEV;
284 803
285 memcpy(data, cap_manufacturer, sizeof(cap_manufacturer)); 804 memcpy(data, tpm_cap, sizeof(tpm_cap));
805 data[TPM_CAP_IDX] = TPM_CAP_PROP;
806 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
286 807
287 if ((len = tpm_transmit(chip, data, sizeof(data))) < 808 rc = transmit_cmd(chip, data, sizeof(data),
288 CAP_MANUFACTURER_RESULT_SIZE) 809 "attempting to determine the manufacturer");
289 return len; 810 if (rc)
811 return 0;
290 812
291 str += sprintf(str, "Manufacturer: 0x%x\n", 813 str += sprintf(str, "Manufacturer: 0x%x\n",
292 be32_to_cpu(*((__be32 *) (data + 14)))); 814 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
293 815
294 memcpy(data, cap_version, sizeof(cap_version)); 816 memcpy(data, cap_version, sizeof(cap_version));
817 data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
818 rc = transmit_cmd(chip, data, sizeof(data),
819 "attempting to determine the 1.1 version");
820 if (rc)
821 goto out;
295 822
296 if ((len = tpm_transmit(chip, data, sizeof(data))) < 823 str += sprintf(str,
297 CAP_VER_RESULT_SIZE) 824 "TCG version: %d.%d\nFirmware version: %d.%d\n",
298 return len; 825 (int) data[14], (int) data[15], (int) data[16],
299 826 (int) data[17]);
300 str +=
301 sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
302 (int) data[14], (int) data[15], (int) data[16],
303 (int) data[17]);
304 827
828out:
305 return str - buf; 829 return str - buf;
306} 830}
307EXPORT_SYMBOL_GPL(tpm_show_caps); 831EXPORT_SYMBOL_GPL(tpm_show_caps);
308 832
833ssize_t tpm_show_caps_1_2(struct device * dev,
834 struct device_attribute * attr, char *buf)
835{
836 u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
837 ssize_t len;
838 char *str = buf;
839
840 struct tpm_chip *chip = dev_get_drvdata(dev);
841 if (chip == NULL)
842 return -ENODEV;
843
844 memcpy(data, tpm_cap, sizeof(tpm_cap));
845 data[TPM_CAP_IDX] = TPM_CAP_PROP;
846 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
847
848 if ((len = tpm_transmit(chip, data, sizeof(data))) <=
849 TPM_ERROR_SIZE) {
850 dev_dbg(chip->dev, "A TPM error (%d) occurred "
851 "attempting to determine the manufacturer\n",
852 be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
853 return 0;
854 }
855
856 str += sprintf(str, "Manufacturer: 0x%x\n",
857 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
858
859 memcpy(data, cap_version, sizeof(cap_version));
860 data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
861
862 if ((len = tpm_transmit(chip, data, sizeof(data))) <=
863 TPM_ERROR_SIZE) {
864 dev_err(chip->dev, "A TPM error (%d) occurred "
865 "attempting to determine the 1.2 version\n",
866 be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
867 goto out;
868 }
869 str += sprintf(str,
870 "TCG version: %d.%d\nFirmware version: %d.%d\n",
871 (int) data[16], (int) data[17], (int) data[18],
872 (int) data[19]);
873
874out:
875 return str - buf;
876}
877EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
878
309ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, 879ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
310 const char *buf, size_t count) 880 const char *buf, size_t count)
311{ 881{
@@ -313,7 +883,7 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
313 if (chip == NULL) 883 if (chip == NULL)
314 return 0; 884 return 0;
315 885
316 chip->vendor->cancel(chip); 886 chip->vendor.cancel(chip);
317 return count; 887 return count;
318} 888}
319EXPORT_SYMBOL_GPL(tpm_store_cancel); 889EXPORT_SYMBOL_GPL(tpm_store_cancel);
@@ -329,7 +899,7 @@ int tpm_open(struct inode *inode, struct file *file)
329 spin_lock(&driver_lock); 899 spin_lock(&driver_lock);
330 900
331 list_for_each_entry(pos, &tpm_chip_list, list) { 901 list_for_each_entry(pos, &tpm_chip_list, list) {
332 if (pos->vendor->miscdev.minor == minor) { 902 if (pos->vendor.miscdev.minor == minor) {
333 chip = pos; 903 chip = pos;
334 break; 904 break;
335 } 905 }
@@ -387,7 +957,7 @@ int tpm_release(struct inode *inode, struct file *file)
387EXPORT_SYMBOL_GPL(tpm_release); 957EXPORT_SYMBOL_GPL(tpm_release);
388 958
389ssize_t tpm_write(struct file *file, const char __user *buf, 959ssize_t tpm_write(struct file *file, const char __user *buf,
390 size_t size, loff_t * off) 960 size_t size, loff_t *off)
391{ 961{
392 struct tpm_chip *chip = file->private_data; 962 struct tpm_chip *chip = file->private_data;
393 int in_size = size, out_size; 963 int in_size = size, out_size;
@@ -419,11 +989,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
419 989
420 return in_size; 990 return in_size;
421} 991}
422
423EXPORT_SYMBOL_GPL(tpm_write); 992EXPORT_SYMBOL_GPL(tpm_write);
424 993
425ssize_t tpm_read(struct file * file, char __user *buf, 994ssize_t tpm_read(struct file *file, char __user *buf,
426 size_t size, loff_t * off) 995 size_t size, loff_t *off)
427{ 996{
428 struct tpm_chip *chip = file->private_data; 997 struct tpm_chip *chip = file->private_data;
429 int ret_size; 998 int ret_size;
@@ -462,14 +1031,13 @@ void tpm_remove_hardware(struct device *dev)
462 spin_unlock(&driver_lock); 1031 spin_unlock(&driver_lock);
463 1032
464 dev_set_drvdata(dev, NULL); 1033 dev_set_drvdata(dev, NULL);
465 misc_deregister(&chip->vendor->miscdev); 1034 misc_deregister(&chip->vendor.miscdev);
466 kfree(chip->vendor->miscdev.name); 1035 kfree(chip->vendor.miscdev.name);
467 1036
468 sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); 1037 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
469 tpm_bios_log_teardown(chip->bios_dir); 1038 tpm_bios_log_teardown(chip->bios_dir);
470 1039
471 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= 1040 clear_bit(chip->dev_num, dev_mask);
472 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
473 1041
474 kfree(chip); 1042 kfree(chip);
475 1043
@@ -520,18 +1088,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
520 * upon errant exit from this function specific probe function should call 1088 * upon errant exit from this function specific probe function should call
521 * pci_disable_device 1089 * pci_disable_device
522 */ 1090 */
523int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) 1091struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
1092 *entry)
524{ 1093{
525#define DEVNAME_SIZE 7 1094#define DEVNAME_SIZE 7
526 1095
527 char *devname; 1096 char *devname;
528 struct tpm_chip *chip; 1097 struct tpm_chip *chip;
529 int i, j;
530 1098
531 /* Driver specific per-device data */ 1099 /* Driver specific per-device data */
532 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1100 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
533 if (chip == NULL) 1101 if (chip == NULL)
534 return -ENOMEM; 1102 return NULL;
535 1103
536 init_MUTEX(&chip->buffer_mutex); 1104 init_MUTEX(&chip->buffer_mutex);
537 init_MUTEX(&chip->tpm_mutex); 1105 init_MUTEX(&chip->tpm_mutex);
@@ -543,45 +1111,37 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
543 chip->user_read_timer.function = user_reader_timeout; 1111 chip->user_read_timer.function = user_reader_timeout;
544 chip->user_read_timer.data = (unsigned long) chip; 1112 chip->user_read_timer.data = (unsigned long) chip;
545 1113
546 chip->vendor = entry; 1114 memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
547
548 chip->dev_num = -1;
549 1115
550 for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++) 1116 chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
551 for (j = 0; j < 8 * sizeof(int); j++)
552 if ((dev_mask[i] & (1 << j)) == 0) {
553 chip->dev_num =
554 i * TPM_NUM_MASK_ENTRIES + j;
555 dev_mask[i] |= 1 << j;
556 goto dev_num_search_complete;
557 }
558 1117
559dev_num_search_complete: 1118 if (chip->dev_num >= TPM_NUM_DEVICES) {
560 if (chip->dev_num < 0) {
561 dev_err(dev, "No available tpm device numbers\n"); 1119 dev_err(dev, "No available tpm device numbers\n");
562 kfree(chip); 1120 kfree(chip);
563 return -ENODEV; 1121 return NULL;
564 } else if (chip->dev_num == 0) 1122 } else if (chip->dev_num == 0)
565 chip->vendor->miscdev.minor = TPM_MINOR; 1123 chip->vendor.miscdev.minor = TPM_MINOR;
566 else 1124 else
567 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; 1125 chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
1126
1127 set_bit(chip->dev_num, dev_mask);
568 1128
569 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); 1129 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
570 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); 1130 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
571 chip->vendor->miscdev.name = devname; 1131 chip->vendor.miscdev.name = devname;
572 1132
573 chip->vendor->miscdev.dev = dev; 1133 chip->vendor.miscdev.dev = dev;
574 chip->dev = get_device(dev); 1134 chip->dev = get_device(dev);
575 1135
576 if (misc_register(&chip->vendor->miscdev)) { 1136 if (misc_register(&chip->vendor.miscdev)) {
577 dev_err(chip->dev, 1137 dev_err(chip->dev,
578 "unable to misc_register %s, minor %d\n", 1138 "unable to misc_register %s, minor %d\n",
579 chip->vendor->miscdev.name, 1139 chip->vendor.miscdev.name,
580 chip->vendor->miscdev.minor); 1140 chip->vendor.miscdev.minor);
581 put_device(dev); 1141 put_device(dev);
1142 clear_bit(chip->dev_num, dev_mask);
582 kfree(chip); 1143 kfree(chip);
583 dev_mask[i] &= !(1 << j); 1144 return NULL;
584 return -ENODEV;
585 } 1145 }
586 1146
587 spin_lock(&driver_lock); 1147 spin_lock(&driver_lock);
@@ -592,11 +1152,11 @@ dev_num_search_complete:
592 1152
593 spin_unlock(&driver_lock); 1153 spin_unlock(&driver_lock);
594 1154
595 sysfs_create_group(&dev->kobj, chip->vendor->attr_group); 1155 sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
596 1156
597 chip->bios_dir = tpm_bios_log_setup(devname); 1157 chip->bios_dir = tpm_bios_log_setup(devname);
598 1158
599 return 0; 1159 return chip;
600} 1160}
601EXPORT_SYMBOL_GPL(tpm_register_hardware); 1161EXPORT_SYMBOL_GPL(tpm_register_hardware);
602 1162
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index dec0224b447..54a4c804e25 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -42,18 +42,30 @@ extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
42 char *); 42 char *);
43extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, 43extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
44 char *); 44 char *);
45extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
46 char *);
45extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, 47extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
46 const char *, size_t); 48 const char *, size_t);
49extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
50 char *);
51extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
52 char *);
53extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
54 char *);
55extern ssize_t tpm_show_temp_deactivated(struct device *,
56 struct device_attribute *attr, char *);
47 57
48struct tpm_chip; 58struct tpm_chip;
49 59
50struct tpm_vendor_specific { 60struct tpm_vendor_specific {
51 u8 req_complete_mask; 61 const u8 req_complete_mask;
52 u8 req_complete_val; 62 const u8 req_complete_val;
53 u8 req_canceled; 63 const u8 req_canceled;
54 void __iomem *iobase; /* ioremapped address */ 64 void __iomem *iobase; /* ioremapped address */
55 unsigned long base; /* TPM base address */ 65 unsigned long base; /* TPM base address */
56 66
67 int irq;
68
57 int region_size; 69 int region_size;
58 int have_region; 70 int have_region;
59 71
@@ -63,6 +75,13 @@ struct tpm_vendor_specific {
63 u8 (*status) (struct tpm_chip *); 75 u8 (*status) (struct tpm_chip *);
64 struct miscdevice miscdev; 76 struct miscdevice miscdev;
65 struct attribute_group *attr_group; 77 struct attribute_group *attr_group;
78 struct list_head list;
79 int locality;
80 unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
81 unsigned long duration[3]; /* jiffies */
82
83 wait_queue_head_t read_queue;
84 wait_queue_head_t int_queue;
66}; 85};
67 86
68struct tpm_chip { 87struct tpm_chip {
@@ -81,13 +100,15 @@ struct tpm_chip {
81 struct work_struct work; 100 struct work_struct work;
82 struct semaphore tpm_mutex; /* tpm is processing */ 101 struct semaphore tpm_mutex; /* tpm is processing */
83 102
84 struct tpm_vendor_specific *vendor; 103 struct tpm_vendor_specific vendor;
85 104
86 struct dentry **bios_dir; 105 struct dentry **bios_dir;
87 106
88 struct list_head list; 107 struct list_head list;
89}; 108};
90 109
110#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
111
91static inline int tpm_read_index(int base, int index) 112static inline int tpm_read_index(int base, int index)
92{ 113{
93 outb(index, base); 114 outb(index, base);
@@ -100,8 +121,12 @@ static inline void tpm_write_index(int base, int index, int value)
100 outb(value & 0xFF, base+1); 121 outb(value & 0xFF, base+1);
101} 122}
102 123
103extern int tpm_register_hardware(struct device *, 124extern void tpm_get_timeouts(struct tpm_chip *);
104 struct tpm_vendor_specific *); 125extern void tpm_gen_interrupt(struct tpm_chip *);
126extern void tpm_continue_selftest(struct tpm_chip *);
127extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
128extern struct tpm_chip* tpm_register_hardware(struct device *,
129 const struct tpm_vendor_specific *);
105extern int tpm_open(struct inode *, struct file *); 130extern int tpm_open(struct inode *, struct file *);
106extern int tpm_release(struct inode *, struct file *); 131extern int tpm_release(struct inode *, struct file *);
107extern ssize_t tpm_write(struct file *, const char __user *, size_t, 132extern ssize_t tpm_write(struct file *, const char __user *, size_t,
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index ff3654964fe..58a258cec15 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
47 return -EIO; 47 return -EIO;
48 48
49 for (i = 0; i < 6; i++) { 49 for (i = 0; i < 6; i++) {
50 status = ioread8(chip->vendor->iobase + 1); 50 status = ioread8(chip->vendor.iobase + 1);
51 if ((status & ATML_STATUS_DATA_AVAIL) == 0) { 51 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
52 dev_err(chip->dev, "error reading header\n"); 52 dev_err(chip->dev, "error reading header\n");
53 return -EIO; 53 return -EIO;
54 } 54 }
55 *buf++ = ioread8(chip->vendor->iobase); 55 *buf++ = ioread8(chip->vendor.iobase);
56 } 56 }
57 57
58 /* size of the data received */ 58 /* size of the data received */
@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
63 dev_err(chip->dev, 63 dev_err(chip->dev,
64 "Recv size(%d) less than available space\n", size); 64 "Recv size(%d) less than available space\n", size);
65 for (; i < size; i++) { /* clear the waiting data anyway */ 65 for (; i < size; i++) { /* clear the waiting data anyway */
66 status = ioread8(chip->vendor->iobase + 1); 66 status = ioread8(chip->vendor.iobase + 1);
67 if ((status & ATML_STATUS_DATA_AVAIL) == 0) { 67 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
68 dev_err(chip->dev, "error reading data\n"); 68 dev_err(chip->dev, "error reading data\n");
69 return -EIO; 69 return -EIO;
@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
74 74
75 /* read all the data available */ 75 /* read all the data available */
76 for (; i < size; i++) { 76 for (; i < size; i++) {
77 status = ioread8(chip->vendor->iobase + 1); 77 status = ioread8(chip->vendor.iobase + 1);
78 if ((status & ATML_STATUS_DATA_AVAIL) == 0) { 78 if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
79 dev_err(chip->dev, "error reading data\n"); 79 dev_err(chip->dev, "error reading data\n");
80 return -EIO; 80 return -EIO;
81 } 81 }
82 *buf++ = ioread8(chip->vendor->iobase); 82 *buf++ = ioread8(chip->vendor.iobase);
83 } 83 }
84 84
85 /* make sure data available is gone */ 85 /* make sure data available is gone */
86 status = ioread8(chip->vendor->iobase + 1); 86 status = ioread8(chip->vendor.iobase + 1);
87 87
88 if (status & ATML_STATUS_DATA_AVAIL) { 88 if (status & ATML_STATUS_DATA_AVAIL) {
89 dev_err(chip->dev, "data available is stuck\n"); 89 dev_err(chip->dev, "data available is stuck\n");
@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
100 dev_dbg(chip->dev, "tpm_atml_send:\n"); 100 dev_dbg(chip->dev, "tpm_atml_send:\n");
101 for (i = 0; i < count; i++) { 101 for (i = 0; i < count; i++) {
102 dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); 102 dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
103 iowrite8(buf[i], chip->vendor->iobase); 103 iowrite8(buf[i], chip->vendor.iobase);
104 } 104 }
105 105
106 return count; 106 return count;
@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
108 108
109static void tpm_atml_cancel(struct tpm_chip *chip) 109static void tpm_atml_cancel(struct tpm_chip *chip)
110{ 110{
111 iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1); 111 iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
112} 112}
113 113
114static u8 tpm_atml_status(struct tpm_chip *chip) 114static u8 tpm_atml_status(struct tpm_chip *chip)
115{ 115{
116 return ioread8(chip->vendor->iobase + 1); 116 return ioread8(chip->vendor.iobase + 1);
117} 117}
118 118
119static struct file_operations atmel_ops = { 119static struct file_operations atmel_ops = {
@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] = {
140 140
141static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; 141static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
142 142
143static struct tpm_vendor_specific tpm_atmel = { 143static const struct tpm_vendor_specific tpm_atmel = {
144 .recv = tpm_atml_recv, 144 .recv = tpm_atml_recv,
145 .send = tpm_atml_send, 145 .send = tpm_atml_send,
146 .cancel = tpm_atml_cancel, 146 .cancel = tpm_atml_cancel,
@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
159 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); 159 struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
160 160
161 if (chip) { 161 if (chip) {
162 if (chip->vendor->have_region) 162 if (chip->vendor.have_region)
163 atmel_release_region(chip->vendor->base, 163 atmel_release_region(chip->vendor.base,
164 chip->vendor->region_size); 164 chip->vendor.region_size);
165 atmel_put_base_addr(chip->vendor); 165 atmel_put_base_addr(chip->vendor.iobase);
166 tpm_remove_hardware(chip->dev); 166 tpm_remove_hardware(chip->dev);
167 platform_device_unregister(pdev); 167 platform_device_unregister(pdev);
168 } 168 }
@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
179static int __init init_atmel(void) 179static int __init init_atmel(void)
180{ 180{
181 int rc = 0; 181 int rc = 0;
182 void __iomem *iobase = NULL;
183 int have_region, region_size;
184 unsigned long base;
185 struct tpm_chip *chip;
182 186
183 driver_register(&atml_drv); 187 driver_register(&atml_drv);
184 188
185 if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) { 189 if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
186 rc = -ENODEV; 190 rc = -ENODEV;
187 goto err_unreg_drv; 191 goto err_unreg_drv;
188 } 192 }
189 193
190 tpm_atmel.have_region = 194 have_region =
191 (atmel_request_region 195 (atmel_request_region
192 (tpm_atmel.base, tpm_atmel.region_size, 196 (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
193 "tpm_atmel0") == NULL) ? 0 : 1; 197
194 198
195 if (IS_ERR 199 if (IS_ERR
196 (pdev = 200 (pdev =
@@ -199,17 +203,25 @@ static int __init init_atmel(void)
199 goto err_rel_reg; 203 goto err_rel_reg;
200 } 204 }
201 205
202 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) 206 if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
207 rc = -ENODEV;
203 goto err_unreg_dev; 208 goto err_unreg_dev;
209 }
210
211 chip->vendor.iobase = iobase;
212 chip->vendor.base = base;
213 chip->vendor.have_region = have_region;
214 chip->vendor.region_size = region_size;
215
204 return 0; 216 return 0;
205 217
206err_unreg_dev: 218err_unreg_dev:
207 platform_device_unregister(pdev); 219 platform_device_unregister(pdev);
208err_rel_reg: 220err_rel_reg:
209 atmel_put_base_addr(&tpm_atmel); 221 atmel_put_base_addr(iobase);
210 if (tpm_atmel.have_region) 222 if (have_region)
211 atmel_release_region(tpm_atmel.base, 223 atmel_release_region(base,
212 tpm_atmel.region_size); 224 region_size);
213err_unreg_drv: 225err_unreg_drv:
214 driver_unregister(&atml_drv); 226 driver_unregister(&atml_drv);
215 return rc; 227 return rc;
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h
index d3478aaadd7..2e68eeb8a2c 100644
--- a/drivers/char/tpm/tpm_atmel.h
+++ b/drivers/char/tpm/tpm_atmel.h
@@ -28,13 +28,12 @@
28#define atmel_request_region request_mem_region 28#define atmel_request_region request_mem_region
29#define atmel_release_region release_mem_region 29#define atmel_release_region release_mem_region
30 30
31static inline void atmel_put_base_addr(struct tpm_vendor_specific 31static inline void atmel_put_base_addr(void __iomem *iobase)
32 *vendor)
33{ 32{
34 iounmap(vendor->iobase); 33 iounmap(iobase);
35} 34}
36 35
37static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor) 36static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
38{ 37{
39 struct device_node *dn; 38 struct device_node *dn;
40 unsigned long address, size; 39 unsigned long address, size;
@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
71 else 70 else
72 size = reg[naddrc]; 71 size = reg[naddrc];
73 72
74 vendor->base = address; 73 *base = address;
75 vendor->region_size = size; 74 *region_size = size;
76 return ioremap(vendor->base, vendor->region_size); 75 return ioremap(*base, *region_size);
77} 76}
78#else 77#else
79#define atmel_getb(chip, offset) inb(chip->vendor->base + offset) 78#define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
106 return 0; 105 return 0;
107} 106}
108 107
109static inline void atmel_put_base_addr(struct tpm_vendor_specific 108static inline void atmel_put_base_addr(void __iomem *iobase)
110 *vendor)
111{ 109{
112} 110}
113 111
114/* Determine where to talk to device */ 112/* Determine where to talk to device */
115static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific 113static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
116 *vendor)
117{ 114{
118 int lo, hi; 115 int lo, hi;
119 116
@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
123 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); 120 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
124 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); 121 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
125 122
126 vendor->base = (hi << 8) | lo; 123 *base = (hi << 8) | lo;
127 vendor->region_size = 2; 124 *region_size = 2;
128 125
129 return ioport_map(vendor->base, vendor->region_size); 126 return ioport_map(*base, *region_size);
130} 127}
131#endif 128#endif
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
index 537aa45d8c6..e45f0d3d12d 100644
--- a/drivers/char/tpm/tpm_bios.c
+++ b/drivers/char/tpm/tpm_bios.c
@@ -29,6 +29,11 @@
29#define MAX_TEXT_EVENT 1000 /* Max event string length */ 29#define MAX_TEXT_EVENT 1000 /* Max event string length */
30#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ 30#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */
31 31
32enum bios_platform_class {
33 BIOS_CLIENT = 0x00,
34 BIOS_SERVER = 0x01,
35};
36
32struct tpm_bios_log { 37struct tpm_bios_log {
33 void *bios_event_log; 38 void *bios_event_log;
34 void *bios_event_log_end; 39 void *bios_event_log_end;
@@ -36,9 +41,18 @@ struct tpm_bios_log {
36 41
37struct acpi_tcpa { 42struct acpi_tcpa {
38 struct acpi_table_header hdr; 43 struct acpi_table_header hdr;
39 u16 reserved; 44 u16 platform_class;
40 u32 log_max_len __attribute__ ((packed)); 45 union {
41 u32 log_start_addr __attribute__ ((packed)); 46 struct client_hdr {
47 u32 log_max_len __attribute__ ((packed));
48 u64 log_start_addr __attribute__ ((packed));
49 } client;
50 struct server_hdr {
51 u16 reserved;
52 u64 log_max_len __attribute__ ((packed));
53 u64 log_start_addr __attribute__ ((packed));
54 } server;
55 };
42}; 56};
43 57
44struct tcpa_event { 58struct tcpa_event {
@@ -120,6 +134,7 @@ static const char* tcpa_pc_event_id_strings[] = {
120 "S-CRTM Version", 134 "S-CRTM Version",
121 "S-CRTM Contents", 135 "S-CRTM Contents",
122 "S-CRTM POST Contents", 136 "S-CRTM POST Contents",
137 "POST Contents",
123}; 138};
124 139
125/* returns pointer to start of pos. entry of tcg log */ 140/* returns pointer to start of pos. entry of tcg log */
@@ -306,6 +321,7 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
306 /* 5th: delimiter */ 321 /* 5th: delimiter */
307 seq_putc(m, '\0'); 322 seq_putc(m, '\0');
308 323
324 kfree(eventname);
309 return 0; 325 return 0;
310} 326}
311 327
@@ -353,6 +369,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
353 /* 4th: eventname <= max + \'0' delimiter */ 369 /* 4th: eventname <= max + \'0' delimiter */
354 seq_printf(m, " %s\n", eventname); 370 seq_printf(m, " %s\n", eventname);
355 371
372 kfree(eventname);
356 return 0; 373 return 0;
357} 374}
358 375
@@ -376,6 +393,7 @@ static int read_log(struct tpm_bios_log *log)
376 struct acpi_tcpa *buff; 393 struct acpi_tcpa *buff;
377 acpi_status status; 394 acpi_status status;
378 struct acpi_table_header *virt; 395 struct acpi_table_header *virt;
396 u64 len, start;
379 397
380 if (log->bios_event_log != NULL) { 398 if (log->bios_event_log != NULL) {
381 printk(KERN_ERR 399 printk(KERN_ERR
@@ -396,27 +414,37 @@ static int read_log(struct tpm_bios_log *log)
396 return -EIO; 414 return -EIO;
397 } 415 }
398 416
399 if (buff->log_max_len == 0) { 417 switch(buff->platform_class) {
418 case BIOS_SERVER:
419 len = buff->server.log_max_len;
420 start = buff->server.log_start_addr;
421 break;
422 case BIOS_CLIENT:
423 default:
424 len = buff->client.log_max_len;
425 start = buff->client.log_start_addr;
426 break;
427 }
428 if (!len) {
400 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); 429 printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
401 return -EIO; 430 return -EIO;
402 } 431 }
403 432
404 /* malloc EventLog space */ 433 /* malloc EventLog space */
405 log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); 434 log->bios_event_log = kmalloc(len, GFP_KERNEL);
406 if (!log->bios_event_log) { 435 if (!log->bios_event_log) {
407 printk 436 printk("%s: ERROR - Not enough Memory for BIOS measurements\n",
408 ("%s: ERROR - Not enough Memory for BIOS measurements\n", 437 __func__);
409 __func__);
410 return -ENOMEM; 438 return -ENOMEM;
411 } 439 }
412 440
413 log->bios_event_log_end = log->bios_event_log + buff->log_max_len; 441 log->bios_event_log_end = log->bios_event_log + len;
414 442
415 acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); 443 acpi_os_map_memory(start, len, (void *) &virt);
416 444
417 memcpy(log->bios_event_log, virt, buff->log_max_len); 445 memcpy(log->bios_event_log, virt, len);
418 446
419 acpi_os_unmap_memory(virt, buff->log_max_len); 447 acpi_os_unmap_memory(virt, len);
420 return 0; 448 return 0;
421} 449}
422 450
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 24095f6ee6d..adfff21beb2 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -15,6 +15,7 @@
15 * License. 15 * License.
16 */ 16 */
17 17
18#include <linux/init.h>
18#include <linux/pnp.h> 19#include <linux/pnp.h>
19#include "tpm.h" 20#include "tpm.h"
20 21
@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
104 105
105 if (clear_wrfifo) { 106 if (clear_wrfifo) {
106 for (i = 0; i < 4096; i++) { 107 for (i = 0; i < 4096; i++) {
107 status = inb(chip->vendor->base + WRFIFO); 108 status = inb(chip->vendor.base + WRFIFO);
108 if (status == 0xff) { 109 if (status == 0xff) {
109 if (check == 5) 110 if (check == 5)
110 break; 111 break;
@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
124 */ 125 */
125 i = 0; 126 i = 0;
126 do { 127 do {
127 status = inb(chip->vendor->base + RDFIFO); 128 status = inb(chip->vendor.base + RDFIFO);
128 status = inb(chip->vendor->base + STAT); 129 status = inb(chip->vendor.base + STAT);
129 i++; 130 i++;
130 if (i == TPM_MAX_TRIES) 131 if (i == TPM_MAX_TRIES)
131 return -EIO; 132 return -EIO;
@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
138 int status; 139 int status;
139 int i; 140 int i;
140 for (i = 0; i < TPM_MAX_TRIES; i++) { 141 for (i = 0; i < TPM_MAX_TRIES; i++) {
141 status = inb(chip->vendor->base + STAT); 142 status = inb(chip->vendor.base + STAT);
142 /* check the status-register if wait_for_bit is set */ 143 /* check the status-register if wait_for_bit is set */
143 if (status & 1 << wait_for_bit) 144 if (status & 1 << wait_for_bit)
144 break; 145 break;
@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
157static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) 158static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
158{ 159{
159 wait(chip, STAT_XFE); 160 wait(chip, STAT_XFE);
160 outb(sendbyte, chip->vendor->base + WRFIFO); 161 outb(sendbyte, chip->vendor.base + WRFIFO);
161} 162}
162 163
163 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more 164 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
@@ -204,7 +205,7 @@ recv_begin:
204 ret = wait(chip, STAT_RDA); 205 ret = wait(chip, STAT_RDA);
205 if (ret) 206 if (ret)
206 return -EIO; 207 return -EIO;
207 buf[i] = inb(chip->vendor->base + RDFIFO); 208 buf[i] = inb(chip->vendor.base + RDFIFO);
208 } 209 }
209 210
210 if (buf[0] != TPM_VL_VER) { 211 if (buf[0] != TPM_VL_VER) {
@@ -219,7 +220,7 @@ recv_begin:
219 220
220 for (i = 0; i < size; i++) { 221 for (i = 0; i < size; i++) {
221 wait(chip, STAT_RDA); 222 wait(chip, STAT_RDA);
222 buf[i] = inb(chip->vendor->base + RDFIFO); 223 buf[i] = inb(chip->vendor.base + RDFIFO);
223 } 224 }
224 225
225 if ((size == 0x6D00) && (buf[1] == 0x80)) { 226 if ((size == 0x6D00) && (buf[1] == 0x80)) {
@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
268 u8 count_high, count_low, count_4, count_3, count_2, count_1; 269 u8 count_high, count_low, count_4, count_3, count_2, count_1;
269 270
270 /* Disabling Reset, LP and IRQC */ 271 /* Disabling Reset, LP and IRQC */
271 outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD); 272 outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
272 273
273 ret = empty_fifo(chip, 1); 274 ret = empty_fifo(chip, 1);
274 if (ret) { 275 if (ret) {
@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
319 320
320static u8 tpm_inf_status(struct tpm_chip *chip) 321static u8 tpm_inf_status(struct tpm_chip *chip)
321{ 322{
322 return inb(chip->vendor->base + STAT); 323 return inb(chip->vendor.base + STAT);
323} 324}
324 325
325static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); 326static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
@@ -346,7 +347,7 @@ static struct file_operations inf_ops = {
346 .release = tpm_release, 347 .release = tpm_release,
347}; 348};
348 349
349static struct tpm_vendor_specific tpm_inf = { 350static const struct tpm_vendor_specific tpm_inf = {
350 .recv = tpm_inf_recv, 351 .recv = tpm_inf_recv,
351 .send = tpm_inf_send, 352 .send = tpm_inf_send,
352 .cancel = tpm_inf_cancel, 353 .cancel = tpm_inf_cancel,
@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
375 int version[2]; 376 int version[2];
376 int productid[2]; 377 int productid[2];
377 char chipname[20]; 378 char chipname[20];
379 struct tpm_chip *chip;
378 380
379 /* read IO-ports through PnP */ 381 /* read IO-ports through PnP */
380 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && 382 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
395 goto err_last; 397 goto err_last;
396 } 398 }
397 /* publish my base address and request region */ 399 /* publish my base address and request region */
398 tpm_inf.base = TPM_INF_BASE;
399 if (request_region 400 if (request_region
400 (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { 401 (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
401 rc = -EINVAL; 402 rc = -EINVAL;
402 goto err_last; 403 goto err_last;
403 } 404 }
404 if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN, 405 if (request_region
405 "tpm_infineon0") == NULL) { 406 (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
406 rc = -EINVAL; 407 rc = -EINVAL;
407 goto err_last; 408 goto err_last;
408 } 409 }
@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
442 443
443 /* configure TPM with IO-ports */ 444 /* configure TPM with IO-ports */
444 outb(IOLIMH, TPM_INF_ADDR); 445 outb(IOLIMH, TPM_INF_ADDR);
445 outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); 446 outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
446 outb(IOLIML, TPM_INF_ADDR); 447 outb(IOLIML, TPM_INF_ADDR);
447 outb((tpm_inf.base & 0xff), TPM_INF_DATA); 448 outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
448 449
449 /* control if IO-ports are set correctly */ 450 /* control if IO-ports are set correctly */
450 outb(IOLIMH, TPM_INF_ADDR); 451 outb(IOLIMH, TPM_INF_ADDR);
@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
452 outb(IOLIML, TPM_INF_ADDR); 453 outb(IOLIML, TPM_INF_ADDR);
453 iol = inb(TPM_INF_DATA); 454 iol = inb(TPM_INF_DATA);
454 455
455 if ((ioh << 8 | iol) != tpm_inf.base) { 456 if ((ioh << 8 | iol) != TPM_INF_BASE) {
456 dev_err(&dev->dev, 457 dev_err(&dev->dev,
457 "Could not set IO-ports to 0x%lx\n", 458 "Could not set IO-ports to 0x%x\n",
458 tpm_inf.base); 459 TPM_INF_BASE);
459 rc = -EIO; 460 rc = -EIO;
460 goto err_release_region; 461 goto err_release_region;
461 } 462 }
@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
466 outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); 467 outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
467 468
468 /* disable RESET, LP and IRQC */ 469 /* disable RESET, LP and IRQC */
469 outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); 470 outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
470 471
471 /* Finally, we're done, print some infos */ 472 /* Finally, we're done, print some infos */
472 dev_info(&dev->dev, "TPM found: " 473 dev_info(&dev->dev, "TPM found: "
473 "config base 0x%x, " 474 "config base 0x%x, "
474 "io base 0x%x, " 475 "io base 0x%x, "
475 "chip version %02x%02x, " 476 "chip version 0x%02x%02x, "
476 "vendor id %x%x (Infineon), " 477 "vendor id 0x%x%x (Infineon), "
477 "product id %02x%02x" 478 "product id 0x%02x%02x"
478 "%s\n", 479 "%s\n",
479 TPM_INF_ADDR, 480 TPM_INF_ADDR,
480 TPM_INF_BASE, 481 TPM_INF_BASE,
@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
482 vendorid[0], vendorid[1], 483 vendorid[0], vendorid[1],
483 productid[0], productid[1], chipname); 484 productid[0], productid[1], chipname);
484 485
485 rc = tpm_register_hardware(&dev->dev, &tpm_inf); 486 if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
486 if (rc < 0) {
487 rc = -ENODEV;
488 goto err_release_region; 487 goto err_release_region;
489 } 488 }
489 chip->vendor.base = TPM_INF_BASE;
490 return 0; 490 return 0;
491 } else { 491 } else {
492 rc = -ENODEV; 492 rc = -ENODEV;
@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
494 } 494 }
495 495
496err_release_region: 496err_release_region:
497 release_region(tpm_inf.base, TPM_INF_PORT_LEN); 497 release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
498 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); 498 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
499 499
500err_last: 500err_last:
@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
506 struct tpm_chip *chip = pnp_get_drvdata(dev); 506 struct tpm_chip *chip = pnp_get_drvdata(dev);
507 507
508 if (chip) { 508 if (chip) {
509 release_region(chip->vendor->base, TPM_INF_PORT_LEN); 509 release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
510 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
510 tpm_remove_hardware(chip->dev); 511 tpm_remove_hardware(chip->dev);
511 } 512 }
512} 513}
@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
520 }, 521 },
521 .id_table = tpm_pnp_tbl, 522 .id_table = tpm_pnp_tbl,
522 .probe = tpm_inf_pnp_probe, 523 .probe = tpm_inf_pnp_probe,
523 .remove = tpm_inf_pnp_remove, 524 .remove = __devexit_p(tpm_inf_pnp_remove),
524}; 525};
525 526
526static int __init init_inf(void) 527static int __init init_inf(void)
@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
538 539
539MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); 540MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
540MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); 541MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
541MODULE_VERSION("1.7"); 542MODULE_VERSION("1.8");
542MODULE_LICENSE("GPL"); 543MODULE_LICENSE("GPL");
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 680a8e33188..4c8bc06c7d9 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
71 unsigned long stop; 71 unsigned long stop;
72 72
73 /* status immediately available check */ 73 /* status immediately available check */
74 *data = inb(chip->vendor->base + NSC_STATUS); 74 *data = inb(chip->vendor.base + NSC_STATUS);
75 if ((*data & mask) == val) 75 if ((*data & mask) == val)
76 return 0; 76 return 0;
77 77
@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
79 stop = jiffies + 10 * HZ; 79 stop = jiffies + 10 * HZ;
80 do { 80 do {
81 msleep(TPM_TIMEOUT); 81 msleep(TPM_TIMEOUT);
82 *data = inb(chip->vendor->base + 1); 82 *data = inb(chip->vendor.base + 1);
83 if ((*data & mask) == val) 83 if ((*data & mask) == val)
84 return 0; 84 return 0;
85 } 85 }
@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
94 unsigned long stop; 94 unsigned long stop;
95 95
96 /* status immediately available check */ 96 /* status immediately available check */
97 status = inb(chip->vendor->base + NSC_STATUS); 97 status = inb(chip->vendor.base + NSC_STATUS);
98 if (status & NSC_STATUS_OBF) 98 if (status & NSC_STATUS_OBF)
99 status = inb(chip->vendor->base + NSC_DATA); 99 status = inb(chip->vendor.base + NSC_DATA);
100 if (status & NSC_STATUS_RDY) 100 if (status & NSC_STATUS_RDY)
101 return 0; 101 return 0;
102 102
@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
104 stop = jiffies + 100; 104 stop = jiffies + 100;
105 do { 105 do {
106 msleep(TPM_TIMEOUT); 106 msleep(TPM_TIMEOUT);
107 status = inb(chip->vendor->base + NSC_STATUS); 107 status = inb(chip->vendor.base + NSC_STATUS);
108 if (status & NSC_STATUS_OBF) 108 if (status & NSC_STATUS_OBF)
109 status = inb(chip->vendor->base + NSC_DATA); 109 status = inb(chip->vendor.base + NSC_DATA);
110 if (status & NSC_STATUS_RDY) 110 if (status & NSC_STATUS_RDY)
111 return 0; 111 return 0;
112 } 112 }
@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
132 return -EIO; 132 return -EIO;
133 } 133 }
134 if ((data = 134 if ((data =
135 inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { 135 inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
136 dev_err(chip->dev, "not in normal mode (0x%x)\n", 136 dev_err(chip->dev, "not in normal mode (0x%x)\n",
137 data); 137 data);
138 return -EIO; 138 return -EIO;
@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
148 } 148 }
149 if (data & NSC_STATUS_F0) 149 if (data & NSC_STATUS_F0)
150 break; 150 break;
151 *p = inb(chip->vendor->base + NSC_DATA); 151 *p = inb(chip->vendor.base + NSC_DATA);
152 } 152 }
153 153
154 if ((data & NSC_STATUS_F0) == 0 && 154 if ((data & NSC_STATUS_F0) == 0 &&
@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
156 dev_err(chip->dev, "F0 not set\n"); 156 dev_err(chip->dev, "F0 not set\n");
157 return -EIO; 157 return -EIO;
158 } 158 }
159 if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { 159 if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
160 dev_err(chip->dev, 160 dev_err(chip->dev,
161 "expected end of command(0x%x)\n", data); 161 "expected end of command(0x%x)\n", data);
162 return -EIO; 162 return -EIO;
@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
182 * fix it. Not sure why this is needed, we followed the flow 182 * fix it. Not sure why this is needed, we followed the flow
183 * chart in the manual to the letter. 183 * chart in the manual to the letter.
184 */ 184 */
185 outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); 185 outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
186 186
187 if (nsc_wait_for_ready(chip) != 0) 187 if (nsc_wait_for_ready(chip) != 0)
188 return -EIO; 188 return -EIO;
@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
192 return -EIO; 192 return -EIO;
193 } 193 }
194 194
195 outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); 195 outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
196 if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { 196 if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
197 dev_err(chip->dev, "IBR timeout\n"); 197 dev_err(chip->dev, "IBR timeout\n");
198 return -EIO; 198 return -EIO;
@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
204 "IBF timeout (while writing data)\n"); 204 "IBF timeout (while writing data)\n");
205 return -EIO; 205 return -EIO;
206 } 206 }
207 outb(buf[i], chip->vendor->base + NSC_DATA); 207 outb(buf[i], chip->vendor.base + NSC_DATA);
208 } 208 }
209 209
210 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 210 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
211 dev_err(chip->dev, "IBF timeout\n"); 211 dev_err(chip->dev, "IBF timeout\n");
212 return -EIO; 212 return -EIO;
213 } 213 }
214 outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); 214 outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
215 215
216 return count; 216 return count;
217} 217}
218 218
219static void tpm_nsc_cancel(struct tpm_chip *chip) 219static void tpm_nsc_cancel(struct tpm_chip *chip)
220{ 220{
221 outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); 221 outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
222} 222}
223 223
224static u8 tpm_nsc_status(struct tpm_chip *chip) 224static u8 tpm_nsc_status(struct tpm_chip *chip)
225{ 225{
226 return inb(chip->vendor->base + NSC_STATUS); 226 return inb(chip->vendor.base + NSC_STATUS);
227} 227}
228 228
229static struct file_operations nsc_ops = { 229static struct file_operations nsc_ops = {
@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = {
250 250
251static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; 251static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
252 252
253static struct tpm_vendor_specific tpm_nsc = { 253static const struct tpm_vendor_specific tpm_nsc = {
254 .recv = tpm_nsc_recv, 254 .recv = tpm_nsc_recv,
255 .send = tpm_nsc_send, 255 .send = tpm_nsc_send,
256 .cancel = tpm_nsc_cancel, 256 .cancel = tpm_nsc_cancel,
@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(struct device *dev)
268{ 268{
269 struct tpm_chip *chip = dev_get_drvdata(dev); 269 struct tpm_chip *chip = dev_get_drvdata(dev);
270 if ( chip ) { 270 if ( chip ) {
271 release_region(chip->vendor->base, 2); 271 release_region(chip->vendor.base, 2);
272 tpm_remove_hardware(chip->dev); 272 tpm_remove_hardware(chip->dev);
273 } 273 }
274} 274}
@@ -286,7 +286,8 @@ static int __init init_nsc(void)
286 int rc = 0; 286 int rc = 0;
287 int lo, hi; 287 int lo, hi;
288 int nscAddrBase = TPM_ADDR; 288 int nscAddrBase = TPM_ADDR;
289 289 struct tpm_chip *chip;
290 unsigned long base;
290 291
291 /* verify that it is a National part (SID) */ 292 /* verify that it is a National part (SID) */
292 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { 293 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,7 +301,7 @@ static int __init init_nsc(void)
300 301
301 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); 302 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
302 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); 303 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
303 tpm_nsc.base = (hi<<8) | lo; 304 base = (hi<<8) | lo;
304 305
305 /* enable the DPM module */ 306 /* enable the DPM module */
306 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); 307 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
@@ -320,13 +321,15 @@ static int __init init_nsc(void)
320 if ((rc = platform_device_register(pdev)) < 0) 321 if ((rc = platform_device_register(pdev)) < 0)
321 goto err_free_dev; 322 goto err_free_dev;
322 323
323 if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { 324 if (request_region(base, 2, "tpm_nsc0") == NULL ) {
324 rc = -EBUSY; 325 rc = -EBUSY;
325 goto err_unreg_dev; 326 goto err_unreg_dev;
326 } 327 }
327 328
328 if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) 329 if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
330 rc = -ENODEV;
329 goto err_rel_reg; 331 goto err_rel_reg;
332 }
330 333
331 dev_dbg(&pdev->dev, "NSC TPM detected\n"); 334 dev_dbg(&pdev->dev, "NSC TPM detected\n");
332 dev_dbg(&pdev->dev, 335 dev_dbg(&pdev->dev,
@@ -361,10 +364,12 @@ static int __init init_nsc(void)
361 "NSC TPM revision %d\n", 364 "NSC TPM revision %d\n",
362 tpm_read_index(nscAddrBase, 0x27) & 0x1F); 365 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
363 366
367 chip->vendor.base = base;
368
364 return 0; 369 return 0;
365 370
366err_rel_reg: 371err_rel_reg:
367 release_region(tpm_nsc.base, 2); 372 release_region(base, 2);
368err_unreg_dev: 373err_unreg_dev:
369 platform_device_unregister(pdev); 374 platform_device_unregister(pdev);
370err_free_dev: 375err_free_dev:
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
new file mode 100644
index 00000000000..b9cae9a238b
--- /dev/null
+++ b/drivers/char/tpm/tpm_tis.c
@@ -0,0 +1,669 @@
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/init.h>
20#include <linux/module.h>
21#include <linux/moduleparam.h>
22#include <linux/pnp.h>
23#include <linux/interrupt.h>
24#include <linux/wait.h>
25#include "tpm.h"
26
27#define TPM_HEADER_SIZE 10
28
29enum tis_access {
30 TPM_ACCESS_VALID = 0x80,
31 TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
32 TPM_ACCESS_REQUEST_PENDING = 0x04,
33 TPM_ACCESS_REQUEST_USE = 0x02,
34};
35
36enum tis_status {
37 TPM_STS_VALID = 0x80,
38 TPM_STS_COMMAND_READY = 0x40,
39 TPM_STS_GO = 0x20,
40 TPM_STS_DATA_AVAIL = 0x10,
41 TPM_STS_DATA_EXPECT = 0x08,
42};
43
44enum tis_int_flags {
45 TPM_GLOBAL_INT_ENABLE = 0x80000000,
46 TPM_INTF_BURST_COUNT_STATIC = 0x100,
47 TPM_INTF_CMD_READY_INT = 0x080,
48 TPM_INTF_INT_EDGE_FALLING = 0x040,
49 TPM_INTF_INT_EDGE_RISING = 0x020,
50 TPM_INTF_INT_LEVEL_LOW = 0x010,
51 TPM_INTF_INT_LEVEL_HIGH = 0x008,
52 TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
53 TPM_INTF_STS_VALID_INT = 0x002,
54 TPM_INTF_DATA_AVAIL_INT = 0x001,
55};
56
57enum tis_defaults {
58 TIS_MEM_BASE = 0xFED4000,
59 TIS_MEM_LEN = 0x5000,
60 TIS_SHORT_TIMEOUT = 750, /* ms */
61 TIS_LONG_TIMEOUT = 2000, /* 2 sec */
62};
63
64#define TPM_ACCESS(l) (0x0000 | ((l) << 12))
65#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12))
66#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12))
67#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12))
68#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12))
69#define TPM_STS(l) (0x0018 | ((l) << 12))
70#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12))
71
72#define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
73#define TPM_RID(l) (0x0F04 | ((l) << 12))
74
75static LIST_HEAD(tis_chips);
76static DEFINE_SPINLOCK(tis_lock);
77
78static int check_locality(struct tpm_chip *chip, int l)
79{
80 if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
81 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
82 (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
83 return chip->vendor.locality = l;
84
85 return -1;
86}
87
88static void release_locality(struct tpm_chip *chip, int l, int force)
89{
90 if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
91 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
92 (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
93 iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
94 chip->vendor.iobase + TPM_ACCESS(l));
95}
96
97static int request_locality(struct tpm_chip *chip, int l)
98{
99 unsigned long stop;
100 long rc;
101
102 if (check_locality(chip, l) >= 0)
103 return l;
104
105 iowrite8(TPM_ACCESS_REQUEST_USE,
106 chip->vendor.iobase + TPM_ACCESS(l));
107
108 if (chip->vendor.irq) {
109 rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
110 (check_locality
111 (chip, l) >= 0),
112 chip->vendor.timeout_a);
113 if (rc > 0)
114 return l;
115
116 } else {
117 /* wait for burstcount */
118 stop = jiffies + chip->vendor.timeout_a;
119 do {
120 if (check_locality(chip, l) >= 0)
121 return l;
122 msleep(TPM_TIMEOUT);
123 }
124 while (time_before(jiffies, stop));
125 }
126 return -1;
127}
128
129static u8 tpm_tis_status(struct tpm_chip *chip)
130{
131 return ioread8(chip->vendor.iobase +
132 TPM_STS(chip->vendor.locality));
133}
134
135static void tpm_tis_ready(struct tpm_chip *chip)
136{
137 /* this causes the current command to be aborted */
138 iowrite8(TPM_STS_COMMAND_READY,
139 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
140}
141
142static int get_burstcount(struct tpm_chip *chip)
143{
144 unsigned long stop;
145 int burstcnt;
146
147 /* wait for burstcount */
148 /* which timeout value, spec has 2 answers (c & d) */
149 stop = jiffies + chip->vendor.timeout_d;
150 do {
151 burstcnt = ioread8(chip->vendor.iobase +
152 TPM_STS(chip->vendor.locality) + 1);
153 burstcnt += ioread8(chip->vendor.iobase +
154 TPM_STS(chip->vendor.locality) +
155 2) << 8;
156 if (burstcnt)
157 return burstcnt;
158 msleep(TPM_TIMEOUT);
159 } while (time_before(jiffies, stop));
160 return -EBUSY;
161}
162
163static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
164 wait_queue_head_t *queue)
165{
166 unsigned long stop;
167 long rc;
168 u8 status;
169
170 /* check current status */
171 status = tpm_tis_status(chip);
172 if ((status & mask) == mask)
173 return 0;
174
175 if (chip->vendor.irq) {
176 rc = wait_event_interruptible_timeout(*queue,
177 ((tpm_tis_status
178 (chip) & mask) ==
179 mask), timeout);
180 if (rc > 0)
181 return 0;
182 } else {
183 stop = jiffies + timeout;
184 do {
185 msleep(TPM_TIMEOUT);
186 status = tpm_tis_status(chip);
187 if ((status & mask) == mask)
188 return 0;
189 } while (time_before(jiffies, stop));
190 }
191 return -ETIME;
192}
193
194static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
195{
196 int size = 0, burstcnt;
197 while (size < count &&
198 wait_for_stat(chip,
199 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
200 chip->vendor.timeout_c,
201 &chip->vendor.read_queue)
202 == 0) {
203 burstcnt = get_burstcount(chip);
204 for (; burstcnt > 0 && size < count; burstcnt--)
205 buf[size++] = ioread8(chip->vendor.iobase +
206 TPM_DATA_FIFO(chip->vendor.
207 locality));
208 }
209 return size;
210}
211
212static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
213{
214 int size = 0;
215 int expected, status;
216
217 if (count < TPM_HEADER_SIZE) {
218 size = -EIO;
219 goto out;
220 }
221
222 /* read first 10 bytes, including tag, paramsize, and result */
223 if ((size =
224 recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
225 dev_err(chip->dev, "Unable to read header\n");
226 goto out;
227 }
228
229 expected = be32_to_cpu(*(__be32 *) (buf + 2));
230 if (expected > count) {
231 size = -EIO;
232 goto out;
233 }
234
235 if ((size +=
236 recv_data(chip, &buf[TPM_HEADER_SIZE],
237 expected - TPM_HEADER_SIZE)) < expected) {
238 dev_err(chip->dev, "Unable to read remainder of result\n");
239 size = -ETIME;
240 goto out;
241 }
242
243 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
244 &chip->vendor.int_queue);
245 status = tpm_tis_status(chip);
246 if (status & TPM_STS_DATA_AVAIL) { /* retry? */
247 dev_err(chip->dev, "Error left over data\n");
248 size = -EIO;
249 goto out;
250 }
251
252out:
253 tpm_tis_ready(chip);
254 release_locality(chip, chip->vendor.locality, 0);
255 return size;
256}
257
258/*
259 * If interrupts are used (signaled by an irq set in the vendor structure)
260 * tpm.c can skip polling for the data to be available as the interrupt is
261 * waited for here
262 */
263static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
264{
265 int rc, status, burstcnt;
266 size_t count = 0;
267 u32 ordinal;
268
269 if (request_locality(chip, 0) < 0)
270 return -EBUSY;
271
272 status = tpm_tis_status(chip);
273 if ((status & TPM_STS_COMMAND_READY) == 0) {
274 tpm_tis_ready(chip);
275 if (wait_for_stat
276 (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
277 &chip->vendor.int_queue) < 0) {
278 rc = -ETIME;
279 goto out_err;
280 }
281 }
282
283 while (count < len - 1) {
284 burstcnt = get_burstcount(chip);
285 for (; burstcnt > 0 && count < len - 1; burstcnt--) {
286 iowrite8(buf[count], chip->vendor.iobase +
287 TPM_DATA_FIFO(chip->vendor.locality));
288 count++;
289 }
290
291 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
292 &chip->vendor.int_queue);
293 status = tpm_tis_status(chip);
294 if ((status & TPM_STS_DATA_EXPECT) == 0) {
295 rc = -EIO;
296 goto out_err;
297 }
298 }
299
300 /* write last byte */
301 iowrite8(buf[count],
302 chip->vendor.iobase +
303 TPM_DATA_FIFO(chip->vendor.locality));
304 wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
305 &chip->vendor.int_queue);
306 status = tpm_tis_status(chip);
307 if ((status & TPM_STS_DATA_EXPECT) != 0) {
308 rc = -EIO;
309 goto out_err;
310 }
311
312 /* go and do it */
313 iowrite8(TPM_STS_GO,
314 chip->vendor.iobase + TPM_STS(chip->vendor.locality));
315
316 if (chip->vendor.irq) {
317 ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
318 if (wait_for_stat
319 (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
320 tpm_calc_ordinal_duration(chip, ordinal),
321 &chip->vendor.read_queue) < 0) {
322 rc = -ETIME;
323 goto out_err;
324 }
325 }
326 return len;
327out_err:
328 tpm_tis_ready(chip);
329 release_locality(chip, chip->vendor.locality, 0);
330 return rc;
331}
332
333static struct file_operations tis_ops = {
334 .owner = THIS_MODULE,
335 .llseek = no_llseek,
336 .open = tpm_open,
337 .read = tpm_read,
338 .write = tpm_write,
339 .release = tpm_release,
340};
341
342static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
343static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
344static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
345static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
346static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
347static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
348 NULL);
349static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
350static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
351
352static struct attribute *tis_attrs[] = {
353 &dev_attr_pubek.attr,
354 &dev_attr_pcrs.attr,
355 &dev_attr_enabled.attr,
356 &dev_attr_active.attr,
357 &dev_attr_owned.attr,
358 &dev_attr_temp_deactivated.attr,
359 &dev_attr_caps.attr,
360 &dev_attr_cancel.attr, NULL,
361};
362
363static struct attribute_group tis_attr_grp = {
364 .attrs = tis_attrs
365};
366
367static struct tpm_vendor_specific tpm_tis = {
368 .status = tpm_tis_status,
369 .recv = tpm_tis_recv,
370 .send = tpm_tis_send,
371 .cancel = tpm_tis_ready,
372 .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
373 .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
374 .req_canceled = TPM_STS_COMMAND_READY,
375 .attr_group = &tis_attr_grp,
376 .miscdev = {
377 .fops = &tis_ops,},
378};
379
380static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
381{
382 struct tpm_chip *chip = (struct tpm_chip *) dev_id;
383 u32 interrupt;
384
385 interrupt = ioread32(chip->vendor.iobase +
386 TPM_INT_STATUS(chip->vendor.locality));
387
388 if (interrupt == 0)
389 return IRQ_NONE;
390
391 chip->vendor.irq = irq;
392
393 /* Clear interrupts handled with TPM_EOI */
394 iowrite32(interrupt,
395 chip->vendor.iobase +
396 TPM_INT_STATUS(chip->vendor.locality));
397 return IRQ_HANDLED;
398}
399
400static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
401{
402 struct tpm_chip *chip = (struct tpm_chip *) dev_id;
403 u32 interrupt;
404 int i;
405
406 interrupt = ioread32(chip->vendor.iobase +
407 TPM_INT_STATUS(chip->vendor.locality));
408
409 if (interrupt == 0)
410 return IRQ_NONE;
411
412 if (interrupt & TPM_INTF_DATA_AVAIL_INT)
413 wake_up_interruptible(&chip->vendor.read_queue);
414 if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
415 for (i = 0; i < 5; i++)
416 if (check_locality(chip, i) >= 0)
417 break;
418 if (interrupt &
419 (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
420 TPM_INTF_CMD_READY_INT))
421 wake_up_interruptible(&chip->vendor.int_queue);
422
423 /* Clear interrupts handled with TPM_EOI */
424 iowrite32(interrupt,
425 chip->vendor.iobase +
426 TPM_INT_STATUS(chip->vendor.locality));
427 return IRQ_HANDLED;
428}
429
430static int interrupts = 1;
431module_param(interrupts, bool, 0444);
432MODULE_PARM_DESC(interrupts, "Enable interrupts");
433
434static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
435 const struct pnp_device_id *pnp_id)
436{
437 u32 vendor, intfcaps, intmask;
438 int rc, i;
439 unsigned long start, len;
440 struct tpm_chip *chip;
441
442 start = pnp_mem_start(pnp_dev, 0);
443 len = pnp_mem_len(pnp_dev, 0);
444
445 if (!start)
446 start = TIS_MEM_BASE;
447 if (!len)
448 len = TIS_MEM_LEN;
449
450 if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
451 return -ENODEV;
452
453 chip->vendor.iobase = ioremap(start, len);
454 if (!chip->vendor.iobase) {
455 rc = -EIO;
456 goto out_err;
457 }
458
459 vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
460 if ((vendor & 0xFFFF) == 0xFFFF) {
461 rc = -ENODEV;
462 goto out_err;
463 }
464
465 /* Default timeouts */
466 chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
467 chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
468 chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
469 chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
470
471 dev_info(&pnp_dev->dev,
472 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
473 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
474
475 /* Figure out the capabilities */
476 intfcaps =
477 ioread32(chip->vendor.iobase +
478 TPM_INTF_CAPS(chip->vendor.locality));
479 dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
480 intfcaps);
481 if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
482 dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
483 if (intfcaps & TPM_INTF_CMD_READY_INT)
484 dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
485 if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
486 dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
487 if (intfcaps & TPM_INTF_INT_EDGE_RISING)
488 dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
489 if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
490 dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
491 if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
492 dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
493 if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
494 dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
495 if (intfcaps & TPM_INTF_STS_VALID_INT)
496 dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
497 if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
498 dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
499
500 if (request_locality(chip, 0) != 0) {
501 rc = -ENODEV;
502 goto out_err;
503 }
504
505 /* INTERRUPT Setup */
506 init_waitqueue_head(&chip->vendor.read_queue);
507 init_waitqueue_head(&chip->vendor.int_queue);
508
509 intmask =
510 ioread32(chip->vendor.iobase +
511 TPM_INT_ENABLE(chip->vendor.locality));
512
513 intmask |= TPM_INTF_CMD_READY_INT
514 | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
515 | TPM_INTF_STS_VALID_INT;
516
517 iowrite32(intmask,
518 chip->vendor.iobase +
519 TPM_INT_ENABLE(chip->vendor.locality));
520 if (interrupts) {
521 chip->vendor.irq =
522 ioread8(chip->vendor.iobase +
523 TPM_INT_VECTOR(chip->vendor.locality));
524
525 for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
526 iowrite8(i, chip->vendor.iobase +
527 TPM_INT_VECTOR(chip->vendor.locality));
528 if (request_irq
529 (i, tis_int_probe, SA_SHIRQ,
530 chip->vendor.miscdev.name, chip) != 0) {
531 dev_info(chip->dev,
532 "Unable to request irq: %d for probe\n",
533 i);
534 continue;
535 }
536
537 /* Clear all existing */
538 iowrite32(ioread32
539 (chip->vendor.iobase +
540 TPM_INT_STATUS(chip->vendor.locality)),
541 chip->vendor.iobase +
542 TPM_INT_STATUS(chip->vendor.locality));
543
544 /* Turn on */
545 iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
546 chip->vendor.iobase +
547 TPM_INT_ENABLE(chip->vendor.locality));
548
549 /* Generate Interrupts */
550 tpm_gen_interrupt(chip);
551
552 /* Turn off */
553 iowrite32(intmask,
554 chip->vendor.iobase +
555 TPM_INT_ENABLE(chip->vendor.locality));
556 free_irq(i, chip);
557 }
558 }
559 if (chip->vendor.irq) {
560 iowrite8(chip->vendor.irq,
561 chip->vendor.iobase +
562 TPM_INT_VECTOR(chip->vendor.locality));
563 if (request_irq
564 (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
565 chip->vendor.miscdev.name, chip) != 0) {
566 dev_info(chip->dev,
567 "Unable to request irq: %d for use\n",
568 chip->vendor.irq);
569 chip->vendor.irq = 0;
570 } else {
571 /* Clear all existing */
572 iowrite32(ioread32
573 (chip->vendor.iobase +
574 TPM_INT_STATUS(chip->vendor.locality)),
575 chip->vendor.iobase +
576 TPM_INT_STATUS(chip->vendor.locality));
577
578 /* Turn on */
579 iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
580 chip->vendor.iobase +
581 TPM_INT_ENABLE(chip->vendor.locality));
582 }
583 }
584
585 INIT_LIST_HEAD(&chip->vendor.list);
586 spin_lock(&tis_lock);
587 list_add(&chip->vendor.list, &tis_chips);
588 spin_unlock(&tis_lock);
589
590 tpm_get_timeouts(chip);
591 tpm_continue_selftest(chip);
592
593 return 0;
594out_err:
595 if (chip->vendor.iobase)
596 iounmap(chip->vendor.iobase);
597 tpm_remove_hardware(chip->dev);
598 return rc;
599}
600
601static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
602{
603 return tpm_pm_suspend(&dev->dev, msg);
604}
605
606static int tpm_tis_pnp_resume(struct pnp_dev *dev)
607{
608 return tpm_pm_resume(&dev->dev);
609}
610
611static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
612 {"PNP0C31", 0}, /* TPM */
613 {"ATM1200", 0}, /* Atmel */
614 {"IFX0102", 0}, /* Infineon */
615 {"BCM0101", 0}, /* Broadcom */
616 {"NSC1200", 0}, /* National */
617 /* Add new here */
618 {"", 0}, /* User Specified */
619 {"", 0} /* Terminator */
620};
621
622static struct pnp_driver tis_pnp_driver = {
623 .name = "tpm_tis",
624 .id_table = tpm_pnp_tbl,
625 .probe = tpm_tis_pnp_init,
626 .suspend = tpm_tis_pnp_suspend,
627 .resume = tpm_tis_pnp_resume,
628};
629
630#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
631module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
632 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
633MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
634
635static int __init init_tis(void)
636{
637 return pnp_register_driver(&tis_pnp_driver);
638}
639
640static void __exit cleanup_tis(void)
641{
642 struct tpm_vendor_specific *i, *j;
643 struct tpm_chip *chip;
644 spin_lock(&tis_lock);
645 list_for_each_entry_safe(i, j, &tis_chips, list) {
646 chip = to_tpm_chip(i);
647 iowrite32(~TPM_GLOBAL_INT_ENABLE &
648 ioread32(chip->vendor.iobase +
649 TPM_INT_ENABLE(chip->vendor.
650 locality)),
651 chip->vendor.iobase +
652 TPM_INT_ENABLE(chip->vendor.locality));
653 release_locality(chip, chip->vendor.locality, 1);
654 if (chip->vendor.irq)
655 free_irq(chip->vendor.irq, chip);
656 iounmap(i->iobase);
657 list_del(&i->list);
658 tpm_remove_hardware(chip->dev);
659 }
660 spin_unlock(&tis_lock);
661 pnp_unregister_driver(&tis_pnp_driver);
662}
663
664module_init(init_tis);
665module_exit(cleanup_tis);
666MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
667MODULE_DESCRIPTION("TPM Driver");
668MODULE_VERSION("2.0");
669MODULE_LICENSE("GPL");