]>
Commit | Line | Data |
---|---|---|
41a5e1cf CR |
1 | /* |
2 | * Copyright (C) 2005, 2006 IBM Corporation | |
3 | * Copyright (C) 2014, 2015 Intel Corporation | |
4 | * | |
5 | * Authors: | |
6 | * Leendert van Doorn <leendert@watson.ibm.com> | |
7 | * Kylene Hall <kjhall@us.ibm.com> | |
8 | * | |
9 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | |
10 | * | |
11 | * Device driver for TCG/TCPA TPM (trusted platform module). | |
12 | * Specifications at www.trustedcomputinggroup.org | |
13 | * | |
14 | * This device driver implements the TPM interface as defined in | |
15 | * the TCG TPM Interface Spec version 1.2, revision 1.0. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or | |
18 | * modify it under the terms of the GNU General Public License as | |
19 | * published by the Free Software Foundation, version 2 of the | |
20 | * License. | |
21 | */ | |
22 | #include <linux/init.h> | |
23 | #include <linux/module.h> | |
24 | #include <linux/moduleparam.h> | |
25 | #include <linux/pnp.h> | |
26 | #include <linux/slab.h> | |
27 | #include <linux/interrupt.h> | |
28 | #include <linux/wait.h> | |
29 | #include <linux/acpi.h> | |
30 | #include <linux/freezer.h> | |
31 | #include "tpm.h" | |
32 | #include "tpm_tis_core.h" | |
33 | ||
34 | /* Before we attempt to access the TPM we must see that the valid bit is set. | |
35 | * The specification says that this bit is 0 at reset and remains 0 until the | |
36 | * 'TPM has gone through its self test and initialization and has established | |
37 | * correct values in the other bits.' | |
38 | */ | |
39 | static int wait_startup(struct tpm_chip *chip, int l) | |
40 | { | |
41 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
42 | unsigned long stop = jiffies + chip->timeout_a; | |
43 | ||
44 | do { | |
45 | int rc; | |
46 | u8 access; | |
47 | ||
48 | rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access); | |
49 | if (rc < 0) | |
50 | return rc; | |
51 | ||
52 | if (access & TPM_ACCESS_VALID) | |
53 | return 0; | |
54 | msleep(TPM_TIMEOUT); | |
55 | } while (time_before(jiffies, stop)); | |
56 | return -1; | |
57 | } | |
58 | ||
59 | static int check_locality(struct tpm_chip *chip, int l) | |
60 | { | |
61 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
62 | int rc; | |
63 | u8 access; | |
64 | ||
65 | rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access); | |
66 | if (rc < 0) | |
67 | return rc; | |
68 | ||
69 | if ((access & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == | |
70 | (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) | |
71 | return priv->locality = l; | |
72 | ||
73 | return -1; | |
74 | } | |
75 | ||
76 | static void release_locality(struct tpm_chip *chip, int l, int force) | |
77 | { | |
78 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
79 | int rc; | |
80 | u8 access; | |
81 | ||
82 | rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access); | |
83 | if (rc < 0) | |
84 | return; | |
85 | ||
86 | if (force || (access & | |
87 | (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == | |
88 | (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) | |
89 | tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); | |
90 | ||
91 | } | |
92 | ||
93 | static int request_locality(struct tpm_chip *chip, int l) | |
94 | { | |
95 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
96 | unsigned long stop, timeout; | |
97 | long rc; | |
98 | ||
99 | if (check_locality(chip, l) >= 0) | |
100 | return l; | |
101 | ||
102 | rc = tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_REQUEST_USE); | |
103 | if (rc < 0) | |
104 | return rc; | |
105 | ||
106 | stop = jiffies + chip->timeout_a; | |
107 | ||
108 | if (chip->flags & TPM_CHIP_FLAG_IRQ) { | |
109 | again: | |
110 | timeout = stop - jiffies; | |
111 | if ((long)timeout <= 0) | |
112 | return -1; | |
113 | rc = wait_event_interruptible_timeout(priv->int_queue, | |
114 | (check_locality | |
115 | (chip, l) >= 0), | |
116 | timeout); | |
117 | if (rc > 0) | |
118 | return l; | |
119 | if (rc == -ERESTARTSYS && freezing(current)) { | |
120 | clear_thread_flag(TIF_SIGPENDING); | |
121 | goto again; | |
122 | } | |
123 | } else { | |
124 | /* wait for burstcount */ | |
125 | do { | |
126 | if (check_locality(chip, l) >= 0) | |
127 | return l; | |
128 | msleep(TPM_TIMEOUT); | |
129 | } while (time_before(jiffies, stop)); | |
130 | } | |
131 | return -1; | |
132 | } | |
133 | ||
134 | static u8 tpm_tis_status(struct tpm_chip *chip) | |
135 | { | |
136 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
137 | int rc; | |
138 | u8 status; | |
139 | ||
140 | rc = tpm_tis_read8(priv, TPM_STS(priv->locality), &status); | |
141 | if (rc < 0) | |
142 | return 0; | |
143 | ||
144 | return status; | |
145 | } | |
146 | ||
147 | static void tpm_tis_ready(struct tpm_chip *chip) | |
148 | { | |
149 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
150 | ||
151 | /* this causes the current command to be aborted */ | |
152 | tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_COMMAND_READY); | |
153 | } | |
154 | ||
155 | static int get_burstcount(struct tpm_chip *chip) | |
156 | { | |
157 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
158 | unsigned long stop; | |
159 | int burstcnt, rc; | |
9754d45e | 160 | u32 value; |
41a5e1cf CR |
161 | |
162 | /* wait for burstcount */ | |
163 | /* which timeout value, spec has 2 answers (c & d) */ | |
164 | stop = jiffies + chip->timeout_d; | |
165 | do { | |
9754d45e | 166 | rc = tpm_tis_read32(priv, TPM_STS(priv->locality), &value); |
41a5e1cf CR |
167 | if (rc < 0) |
168 | return rc; | |
169 | ||
9754d45e | 170 | burstcnt = (value >> 8) & 0xFFFF; |
41a5e1cf CR |
171 | if (burstcnt) |
172 | return burstcnt; | |
173 | msleep(TPM_TIMEOUT); | |
174 | } while (time_before(jiffies, stop)); | |
175 | return -EBUSY; | |
176 | } | |
177 | ||
178 | static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) | |
179 | { | |
180 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
181 | int size = 0, burstcnt, rc; | |
182 | ||
183 | while (size < count && | |
184 | wait_for_tpm_stat(chip, | |
185 | TPM_STS_DATA_AVAIL | TPM_STS_VALID, | |
186 | chip->timeout_c, | |
187 | &priv->read_queue, true) == 0) { | |
188 | burstcnt = min_t(int, get_burstcount(chip), count - size); | |
189 | ||
190 | rc = tpm_tis_read_bytes(priv, TPM_DATA_FIFO(priv->locality), | |
191 | burstcnt, buf + size); | |
192 | if (rc < 0) | |
193 | return rc; | |
194 | ||
195 | size += burstcnt; | |
196 | } | |
197 | return size; | |
198 | } | |
199 | ||
200 | static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |
201 | { | |
202 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
203 | int size = 0; | |
204 | int expected, status; | |
205 | ||
206 | if (count < TPM_HEADER_SIZE) { | |
207 | size = -EIO; | |
208 | goto out; | |
209 | } | |
210 | ||
211 | size = recv_data(chip, buf, TPM_HEADER_SIZE); | |
212 | /* read first 10 bytes, including tag, paramsize, and result */ | |
213 | if (size < TPM_HEADER_SIZE) { | |
214 | dev_err(&chip->dev, "Unable to read header\n"); | |
215 | goto out; | |
216 | } | |
217 | ||
218 | expected = be32_to_cpu(*(__be32 *) (buf + 2)); | |
219 | if (expected > count) { | |
220 | size = -EIO; | |
221 | goto out; | |
222 | } | |
223 | ||
224 | size += recv_data(chip, &buf[TPM_HEADER_SIZE], | |
225 | expected - TPM_HEADER_SIZE); | |
226 | if (size < expected) { | |
227 | dev_err(&chip->dev, "Unable to read remainder of result\n"); | |
228 | size = -ETIME; | |
229 | goto out; | |
230 | } | |
231 | ||
232 | wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, | |
233 | &priv->int_queue, false); | |
234 | status = tpm_tis_status(chip); | |
235 | if (status & TPM_STS_DATA_AVAIL) { /* retry? */ | |
236 | dev_err(&chip->dev, "Error left over data\n"); | |
237 | size = -EIO; | |
238 | goto out; | |
239 | } | |
240 | ||
241 | out: | |
242 | tpm_tis_ready(chip); | |
243 | release_locality(chip, priv->locality, 0); | |
244 | return size; | |
245 | } | |
246 | ||
247 | /* | |
248 | * If interrupts are used (signaled by an irq set in the vendor structure) | |
249 | * tpm.c can skip polling for the data to be available as the interrupt is | |
250 | * waited for here | |
251 | */ | |
252 | static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len) | |
253 | { | |
254 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
255 | int rc, status, burstcnt; | |
256 | size_t count = 0; | |
257 | bool itpm = priv->flags & TPM_TIS_ITPM_POSSIBLE; | |
258 | ||
259 | if (request_locality(chip, 0) < 0) | |
260 | return -EBUSY; | |
261 | ||
262 | status = tpm_tis_status(chip); | |
263 | if ((status & TPM_STS_COMMAND_READY) == 0) { | |
264 | tpm_tis_ready(chip); | |
265 | if (wait_for_tpm_stat | |
266 | (chip, TPM_STS_COMMAND_READY, chip->timeout_b, | |
267 | &priv->int_queue, false) < 0) { | |
268 | rc = -ETIME; | |
269 | goto out_err; | |
270 | } | |
271 | } | |
272 | ||
273 | while (count < len - 1) { | |
274 | burstcnt = min_t(int, get_burstcount(chip), len - count - 1); | |
275 | rc = tpm_tis_write_bytes(priv, TPM_DATA_FIFO(priv->locality), | |
276 | burstcnt, buf + count); | |
277 | if (rc < 0) | |
278 | goto out_err; | |
279 | ||
280 | count += burstcnt; | |
281 | ||
282 | wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, | |
283 | &priv->int_queue, false); | |
284 | status = tpm_tis_status(chip); | |
285 | if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) { | |
286 | rc = -EIO; | |
287 | goto out_err; | |
288 | } | |
289 | } | |
290 | ||
291 | /* write last byte */ | |
292 | rc = tpm_tis_write8(priv, TPM_DATA_FIFO(priv->locality), buf[count]); | |
293 | if (rc < 0) | |
294 | goto out_err; | |
295 | ||
296 | wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c, | |
297 | &priv->int_queue, false); | |
298 | status = tpm_tis_status(chip); | |
299 | if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) { | |
300 | rc = -EIO; | |
301 | goto out_err; | |
302 | } | |
303 | ||
304 | return 0; | |
305 | ||
306 | out_err: | |
307 | tpm_tis_ready(chip); | |
308 | release_locality(chip, priv->locality, 0); | |
309 | return rc; | |
310 | } | |
311 | ||
312 | static void disable_interrupts(struct tpm_chip *chip) | |
313 | { | |
314 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
315 | u32 intmask; | |
316 | int rc; | |
317 | ||
318 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); | |
319 | if (rc < 0) | |
320 | intmask = 0; | |
321 | ||
322 | intmask &= ~TPM_GLOBAL_INT_ENABLE; | |
323 | rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); | |
324 | ||
325 | devm_free_irq(chip->dev.parent, priv->irq, chip); | |
326 | priv->irq = 0; | |
327 | chip->flags &= ~TPM_CHIP_FLAG_IRQ; | |
328 | } | |
329 | ||
330 | /* | |
331 | * If interrupts are used (signaled by an irq set in the vendor structure) | |
332 | * tpm.c can skip polling for the data to be available as the interrupt is | |
333 | * waited for here | |
334 | */ | |
335 | static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len) | |
336 | { | |
337 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
338 | int rc; | |
339 | u32 ordinal; | |
340 | unsigned long dur; | |
341 | ||
342 | rc = tpm_tis_send_data(chip, buf, len); | |
343 | if (rc < 0) | |
344 | return rc; | |
345 | ||
346 | /* go and do it */ | |
347 | rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO); | |
348 | if (rc < 0) | |
349 | goto out_err; | |
350 | ||
351 | if (chip->flags & TPM_CHIP_FLAG_IRQ) { | |
352 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); | |
353 | ||
354 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | |
355 | dur = tpm2_calc_ordinal_duration(chip, ordinal); | |
356 | else | |
357 | dur = tpm_calc_ordinal_duration(chip, ordinal); | |
358 | ||
359 | if (wait_for_tpm_stat | |
360 | (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, dur, | |
361 | &priv->read_queue, false) < 0) { | |
362 | rc = -ETIME; | |
363 | goto out_err; | |
364 | } | |
365 | } | |
366 | return len; | |
367 | out_err: | |
368 | tpm_tis_ready(chip); | |
369 | release_locality(chip, priv->locality, 0); | |
370 | return rc; | |
371 | } | |
372 | ||
373 | static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) | |
374 | { | |
375 | int rc, irq; | |
376 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
377 | ||
378 | if (!(chip->flags & TPM_CHIP_FLAG_IRQ) || priv->irq_tested) | |
379 | return tpm_tis_send_main(chip, buf, len); | |
380 | ||
381 | /* Verify receipt of the expected IRQ */ | |
382 | irq = priv->irq; | |
383 | priv->irq = 0; | |
384 | chip->flags &= ~TPM_CHIP_FLAG_IRQ; | |
385 | rc = tpm_tis_send_main(chip, buf, len); | |
386 | priv->irq = irq; | |
387 | chip->flags |= TPM_CHIP_FLAG_IRQ; | |
388 | if (!priv->irq_tested) | |
389 | msleep(1); | |
390 | if (!priv->irq_tested) | |
391 | disable_interrupts(chip); | |
392 | priv->irq_tested = true; | |
393 | return rc; | |
394 | } | |
395 | ||
396 | struct tis_vendor_timeout_override { | |
397 | u32 did_vid; | |
398 | unsigned long timeout_us[4]; | |
399 | }; | |
400 | ||
401 | static const struct tis_vendor_timeout_override vendor_timeout_overrides[] = { | |
402 | /* Atmel 3204 */ | |
403 | { 0x32041114, { (TIS_SHORT_TIMEOUT*1000), (TIS_LONG_TIMEOUT*1000), | |
404 | (TIS_SHORT_TIMEOUT*1000), (TIS_SHORT_TIMEOUT*1000) } }, | |
405 | }; | |
406 | ||
407 | static bool tpm_tis_update_timeouts(struct tpm_chip *chip, | |
408 | unsigned long *timeout_cap) | |
409 | { | |
410 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
411 | int i, rc; | |
412 | u32 did_vid; | |
413 | ||
414 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid); | |
415 | if (rc < 0) | |
416 | return rc; | |
417 | ||
418 | for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { | |
419 | if (vendor_timeout_overrides[i].did_vid != did_vid) | |
420 | continue; | |
421 | memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, | |
422 | sizeof(vendor_timeout_overrides[i].timeout_us)); | |
423 | return true; | |
424 | } | |
425 | ||
426 | return false; | |
427 | } | |
428 | ||
429 | /* | |
430 | * Early probing for iTPM with STS_DATA_EXPECT flaw. | |
431 | * Try sending command without itpm flag set and if that | |
432 | * fails, repeat with itpm flag set. | |
433 | */ | |
434 | static int probe_itpm(struct tpm_chip *chip) | |
435 | { | |
436 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
437 | int rc = 0; | |
438 | u8 cmd_getticks[] = { | |
439 | 0x00, 0xc1, 0x00, 0x00, 0x00, 0x0a, | |
440 | 0x00, 0x00, 0x00, 0xf1 | |
441 | }; | |
442 | size_t len = sizeof(cmd_getticks); | |
443 | bool itpm; | |
444 | u16 vendor; | |
445 | ||
446 | rc = tpm_tis_read16(priv, TPM_DID_VID(0), &vendor); | |
447 | if (rc < 0) | |
448 | return rc; | |
449 | ||
450 | /* probe only iTPMS */ | |
451 | if (vendor != TPM_VID_INTEL) | |
452 | return 0; | |
453 | ||
454 | itpm = false; | |
455 | ||
456 | rc = tpm_tis_send_data(chip, cmd_getticks, len); | |
457 | if (rc == 0) | |
458 | goto out; | |
459 | ||
460 | tpm_tis_ready(chip); | |
461 | release_locality(chip, priv->locality, 0); | |
462 | ||
463 | itpm = true; | |
464 | ||
465 | rc = tpm_tis_send_data(chip, cmd_getticks, len); | |
466 | if (rc == 0) { | |
467 | dev_info(&chip->dev, "Detected an iTPM.\n"); | |
468 | rc = 1; | |
469 | } else | |
470 | rc = -EFAULT; | |
471 | ||
472 | out: | |
473 | tpm_tis_ready(chip); | |
474 | release_locality(chip, priv->locality, 0); | |
475 | ||
476 | return rc; | |
477 | } | |
478 | ||
479 | static bool tpm_tis_req_canceled(struct tpm_chip *chip, u8 status) | |
480 | { | |
481 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
482 | ||
483 | switch (priv->manufacturer_id) { | |
484 | case TPM_VID_WINBOND: | |
485 | return ((status == TPM_STS_VALID) || | |
486 | (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY))); | |
487 | case TPM_VID_STM: | |
488 | return (status == (TPM_STS_VALID | TPM_STS_COMMAND_READY)); | |
489 | default: | |
490 | return (status == TPM_STS_COMMAND_READY); | |
491 | } | |
492 | } | |
493 | ||
494 | static irqreturn_t tis_int_handler(int dummy, void *dev_id) | |
495 | { | |
496 | struct tpm_chip *chip = dev_id; | |
497 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
498 | u32 interrupt; | |
499 | int i, rc; | |
500 | ||
501 | rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt); | |
502 | if (rc < 0) | |
503 | return IRQ_NONE; | |
504 | ||
505 | if (interrupt == 0) | |
506 | return IRQ_NONE; | |
507 | ||
508 | priv->irq_tested = true; | |
509 | if (interrupt & TPM_INTF_DATA_AVAIL_INT) | |
510 | wake_up_interruptible(&priv->read_queue); | |
511 | if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT) | |
512 | for (i = 0; i < 5; i++) | |
513 | if (check_locality(chip, i) >= 0) | |
514 | break; | |
515 | if (interrupt & | |
516 | (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT | | |
517 | TPM_INTF_CMD_READY_INT)) | |
518 | wake_up_interruptible(&priv->int_queue); | |
519 | ||
520 | /* Clear interrupts handled with TPM_EOI */ | |
521 | rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), interrupt); | |
522 | if (rc < 0) | |
523 | return IRQ_NONE; | |
524 | ||
525 | tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &interrupt); | |
526 | return IRQ_HANDLED; | |
527 | } | |
528 | ||
eb5854e7 JS |
529 | static int tpm_tis_gen_interrupt(struct tpm_chip *chip) |
530 | { | |
531 | const char *desc = "attempting to generate an interrupt"; | |
532 | u32 cap2; | |
533 | cap_t cap; | |
534 | ||
535 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | |
536 | return tpm2_get_tpm_pt(chip, 0x100, &cap2, desc); | |
537 | else | |
538 | return tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, desc); | |
539 | } | |
540 | ||
41a5e1cf CR |
541 | /* Register the IRQ and issue a command that will cause an interrupt. If an |
542 | * irq is seen then leave the chip setup for IRQ operation, otherwise reverse | |
543 | * everything and leave in polling mode. Returns 0 on success. | |
544 | */ | |
545 | static int tpm_tis_probe_irq_single(struct tpm_chip *chip, u32 intmask, | |
546 | int flags, int irq) | |
547 | { | |
548 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
549 | u8 original_int_vec; | |
550 | int rc; | |
551 | u32 int_status; | |
552 | ||
553 | if (devm_request_irq(chip->dev.parent, irq, tis_int_handler, flags, | |
554 | dev_name(&chip->dev), chip) != 0) { | |
555 | dev_info(&chip->dev, "Unable to request irq: %d for probe\n", | |
556 | irq); | |
557 | return -1; | |
558 | } | |
559 | priv->irq = irq; | |
560 | ||
561 | rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality), | |
562 | &original_int_vec); | |
563 | if (rc < 0) | |
564 | return rc; | |
565 | ||
566 | rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), irq); | |
567 | if (rc < 0) | |
568 | return rc; | |
569 | ||
570 | rc = tpm_tis_read32(priv, TPM_INT_STATUS(priv->locality), &int_status); | |
571 | if (rc < 0) | |
572 | return rc; | |
573 | ||
574 | /* Clear all existing */ | |
575 | rc = tpm_tis_write32(priv, TPM_INT_STATUS(priv->locality), int_status); | |
576 | if (rc < 0) | |
577 | return rc; | |
578 | ||
579 | /* Turn on */ | |
580 | rc = tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), | |
581 | intmask | TPM_GLOBAL_INT_ENABLE); | |
582 | if (rc < 0) | |
583 | return rc; | |
584 | ||
585 | priv->irq_tested = false; | |
586 | ||
587 | /* Generate an interrupt by having the core call through to | |
588 | * tpm_tis_send | |
589 | */ | |
eb5854e7 JS |
590 | rc = tpm_tis_gen_interrupt(chip); |
591 | if (rc < 0) | |
592 | return rc; | |
41a5e1cf CR |
593 | |
594 | /* tpm_tis_send will either confirm the interrupt is working or it | |
595 | * will call disable_irq which undoes all of the above. | |
596 | */ | |
597 | if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) { | |
598 | rc = tpm_tis_write8(priv, original_int_vec, | |
599 | TPM_INT_VECTOR(priv->locality)); | |
600 | if (rc < 0) | |
601 | return rc; | |
602 | ||
603 | return 1; | |
604 | } | |
605 | ||
606 | return 0; | |
607 | } | |
608 | ||
609 | /* Try to find the IRQ the TPM is using. This is for legacy x86 systems that | |
610 | * do not have ACPI/etc. We typically expect the interrupt to be declared if | |
611 | * present. | |
612 | */ | |
613 | static void tpm_tis_probe_irq(struct tpm_chip *chip, u32 intmask) | |
614 | { | |
615 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
616 | u8 original_int_vec; | |
617 | int i, rc; | |
618 | ||
619 | rc = tpm_tis_read8(priv, TPM_INT_VECTOR(priv->locality), | |
620 | &original_int_vec); | |
621 | if (rc < 0) | |
622 | return; | |
623 | ||
624 | if (!original_int_vec) { | |
625 | if (IS_ENABLED(CONFIG_X86)) | |
626 | for (i = 3; i <= 15; i++) | |
627 | if (!tpm_tis_probe_irq_single(chip, intmask, 0, | |
628 | i)) | |
629 | return; | |
630 | } else if (!tpm_tis_probe_irq_single(chip, intmask, 0, | |
631 | original_int_vec)) | |
632 | return; | |
633 | } | |
634 | ||
635 | void tpm_tis_remove(struct tpm_chip *chip) | |
636 | { | |
637 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
638 | u32 reg = TPM_INT_ENABLE(priv->locality); | |
639 | u32 interrupt; | |
640 | int rc; | |
641 | ||
642 | rc = tpm_tis_read32(priv, reg, &interrupt); | |
643 | if (rc < 0) | |
644 | interrupt = 0; | |
645 | ||
646 | tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); | |
647 | release_locality(chip, priv->locality, 1); | |
648 | } | |
649 | EXPORT_SYMBOL_GPL(tpm_tis_remove); | |
650 | ||
651 | static const struct tpm_class_ops tpm_tis = { | |
cae8b441 | 652 | .flags = TPM_OPS_AUTO_STARTUP, |
41a5e1cf CR |
653 | .status = tpm_tis_status, |
654 | .recv = tpm_tis_recv, | |
655 | .send = tpm_tis_send, | |
656 | .cancel = tpm_tis_ready, | |
657 | .update_timeouts = tpm_tis_update_timeouts, | |
658 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | |
659 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | |
660 | .req_canceled = tpm_tis_req_canceled, | |
661 | }; | |
662 | ||
663 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | |
664 | const struct tpm_tis_phy_ops *phy_ops, | |
665 | acpi_handle acpi_dev_handle) | |
666 | { | |
667 | u32 vendor, intfcaps, intmask; | |
668 | u8 rid; | |
669 | int rc, probe; | |
670 | struct tpm_chip *chip; | |
671 | ||
672 | chip = tpmm_chip_alloc(dev, &tpm_tis); | |
673 | if (IS_ERR(chip)) | |
674 | return PTR_ERR(chip); | |
675 | ||
676 | #ifdef CONFIG_ACPI | |
677 | chip->acpi_dev_handle = acpi_dev_handle; | |
678 | #endif | |
679 | ||
680 | /* Maximum timeouts */ | |
79b591c0 | 681 | chip->timeout_a = msecs_to_jiffies(TIS_TIMEOUT_A_MAX); |
682 | chip->timeout_b = msecs_to_jiffies(TIS_TIMEOUT_B_MAX); | |
683 | chip->timeout_c = msecs_to_jiffies(TIS_TIMEOUT_C_MAX); | |
684 | chip->timeout_d = msecs_to_jiffies(TIS_TIMEOUT_D_MAX); | |
41a5e1cf CR |
685 | priv->phy_ops = phy_ops; |
686 | dev_set_drvdata(&chip->dev, priv); | |
687 | ||
688 | if (wait_startup(chip, 0) != 0) { | |
689 | rc = -ENODEV; | |
690 | goto out_err; | |
691 | } | |
692 | ||
693 | /* Take control of the TPM's interrupt hardware and shut it off */ | |
694 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); | |
695 | if (rc < 0) | |
696 | goto out_err; | |
697 | ||
698 | intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | | |
699 | TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; | |
700 | intmask &= ~TPM_GLOBAL_INT_ENABLE; | |
701 | tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); | |
702 | ||
703 | if (request_locality(chip, 0) != 0) { | |
704 | rc = -ENODEV; | |
705 | goto out_err; | |
706 | } | |
707 | ||
708 | rc = tpm2_probe(chip); | |
709 | if (rc) | |
710 | goto out_err; | |
711 | ||
712 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); | |
713 | if (rc < 0) | |
714 | goto out_err; | |
715 | ||
716 | priv->manufacturer_id = vendor; | |
717 | ||
718 | rc = tpm_tis_read8(priv, TPM_RID(0), &rid); | |
719 | if (rc < 0) | |
720 | goto out_err; | |
721 | ||
722 | dev_info(dev, "%s TPM (device-id 0x%X, rev-id %d)\n", | |
723 | (chip->flags & TPM_CHIP_FLAG_TPM2) ? "2.0" : "1.2", | |
724 | vendor >> 16, rid); | |
725 | ||
726 | if (!(priv->flags & TPM_TIS_ITPM_POSSIBLE)) { | |
727 | probe = probe_itpm(chip); | |
728 | if (probe < 0) { | |
729 | rc = -ENODEV; | |
730 | goto out_err; | |
731 | } | |
732 | ||
733 | if (!!probe) | |
734 | priv->flags |= TPM_TIS_ITPM_POSSIBLE; | |
735 | } | |
736 | ||
737 | /* Figure out the capabilities */ | |
738 | rc = tpm_tis_read32(priv, TPM_INTF_CAPS(priv->locality), &intfcaps); | |
739 | if (rc < 0) | |
740 | goto out_err; | |
741 | ||
742 | dev_dbg(dev, "TPM interface capabilities (0x%x):\n", | |
743 | intfcaps); | |
744 | if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) | |
745 | dev_dbg(dev, "\tBurst Count Static\n"); | |
746 | if (intfcaps & TPM_INTF_CMD_READY_INT) | |
747 | dev_dbg(dev, "\tCommand Ready Int Support\n"); | |
748 | if (intfcaps & TPM_INTF_INT_EDGE_FALLING) | |
749 | dev_dbg(dev, "\tInterrupt Edge Falling\n"); | |
750 | if (intfcaps & TPM_INTF_INT_EDGE_RISING) | |
751 | dev_dbg(dev, "\tInterrupt Edge Rising\n"); | |
752 | if (intfcaps & TPM_INTF_INT_LEVEL_LOW) | |
753 | dev_dbg(dev, "\tInterrupt Level Low\n"); | |
754 | if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) | |
755 | dev_dbg(dev, "\tInterrupt Level High\n"); | |
756 | if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) | |
757 | dev_dbg(dev, "\tLocality Change Int Support\n"); | |
758 | if (intfcaps & TPM_INTF_STS_VALID_INT) | |
759 | dev_dbg(dev, "\tSts Valid Int Support\n"); | |
760 | if (intfcaps & TPM_INTF_DATA_AVAIL_INT) | |
761 | dev_dbg(dev, "\tData Avail Int Support\n"); | |
762 | ||
763 | /* Very early on issue a command to the TPM in polling mode to make | |
764 | * sure it works. May as well use that command to set the proper | |
765 | * timeouts for the driver. | |
766 | */ | |
767 | if (tpm_get_timeouts(chip)) { | |
768 | dev_err(dev, "Could not get TPM timeouts and durations\n"); | |
769 | rc = -ENODEV; | |
770 | goto out_err; | |
771 | } | |
772 | ||
773 | /* INTERRUPT Setup */ | |
774 | init_waitqueue_head(&priv->read_queue); | |
775 | init_waitqueue_head(&priv->int_queue); | |
776 | if (irq != -1) { | |
777 | if (irq) { | |
778 | tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED, | |
779 | irq); | |
780 | if (!(chip->flags & TPM_CHIP_FLAG_IRQ)) | |
781 | dev_err(&chip->dev, FW_BUG | |
782 | "TPM interrupt not working, polling instead\n"); | |
783 | } else { | |
784 | tpm_tis_probe_irq(chip, intmask); | |
785 | } | |
786 | } | |
787 | ||
41a5e1cf CR |
788 | return tpm_chip_register(chip); |
789 | out_err: | |
790 | tpm_tis_remove(chip); | |
791 | return rc; | |
792 | } | |
793 | EXPORT_SYMBOL_GPL(tpm_tis_core_init); | |
794 | ||
795 | #ifdef CONFIG_PM_SLEEP | |
796 | static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) | |
797 | { | |
798 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | |
799 | u32 intmask; | |
800 | int rc; | |
801 | ||
802 | /* reenable interrupts that device may have lost or | |
803 | * BIOS/firmware may have disabled | |
804 | */ | |
805 | rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq); | |
806 | if (rc < 0) | |
807 | return; | |
808 | ||
809 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); | |
810 | if (rc < 0) | |
811 | return; | |
812 | ||
813 | intmask |= TPM_INTF_CMD_READY_INT | |
814 | | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | |
815 | | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE; | |
816 | ||
817 | tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); | |
818 | } | |
819 | ||
820 | int tpm_tis_resume(struct device *dev) | |
821 | { | |
822 | struct tpm_chip *chip = dev_get_drvdata(dev); | |
823 | int ret; | |
824 | ||
825 | if (chip->flags & TPM_CHIP_FLAG_IRQ) | |
826 | tpm_tis_reenable_interrupts(chip); | |
827 | ||
828 | ret = tpm_pm_resume(dev); | |
829 | if (ret) | |
830 | return ret; | |
831 | ||
832 | /* TPM 1.2 requires self-test on resume. This function actually returns | |
833 | * an error code but for unknown reason it isn't handled. | |
834 | */ | |
835 | if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) | |
836 | tpm_do_selftest(chip); | |
837 | ||
838 | return 0; | |
839 | } | |
840 | EXPORT_SYMBOL_GPL(tpm_tis_resume); | |
841 | #endif | |
842 | ||
843 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); | |
844 | MODULE_DESCRIPTION("TPM Driver"); | |
845 | MODULE_VERSION("2.0"); | |
846 | MODULE_LICENSE("GPL"); |