.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2012-2020 IBM Corporation |
---|
3 | 4 | * |
---|
.. | .. |
---|
7 | 8 | * |
---|
8 | 9 | * Device driver for TCG/TCPA TPM (trusted platform module). |
---|
9 | 10 | * Specifications at www.trustedcomputinggroup.org |
---|
10 | | - * |
---|
11 | | - * This program is free software; you can redistribute it and/or |
---|
12 | | - * modify it under the terms of the GNU General Public License as |
---|
13 | | - * published by the Free Software Foundation, version 2 of the |
---|
14 | | - * License. |
---|
15 | | - * |
---|
16 | 11 | */ |
---|
17 | 12 | |
---|
18 | 13 | #include <linux/dma-mapping.h> |
---|
.. | .. |
---|
34 | 29 | |
---|
35 | 30 | static const struct vio_device_id tpm_ibmvtpm_device_table[] = { |
---|
36 | 31 | { "IBM,vtpm", "IBM,vtpm"}, |
---|
| 32 | + { "IBM,vtpm", "IBM,vtpm20"}, |
---|
37 | 33 | { "", "" } |
---|
38 | 34 | }; |
---|
39 | 35 | MODULE_DEVICE_TABLE(vio, tpm_ibmvtpm_device_table); |
---|
40 | 36 | |
---|
41 | 37 | /** |
---|
42 | | - * |
---|
43 | | - * ibmvtpm_send_crq_word - Send a CRQ request |
---|
| 38 | + * ibmvtpm_send_crq_word() - Send a CRQ request |
---|
44 | 39 | * @vdev: vio device struct |
---|
45 | 40 | * @w1: pre-constructed first word of tpm crq (second word is reserved) |
---|
46 | 41 | * |
---|
.. | .. |
---|
54 | 49 | } |
---|
55 | 50 | |
---|
56 | 51 | /** |
---|
57 | | - * |
---|
58 | | - * ibmvtpm_send_crq - Send a CRQ request |
---|
| 52 | + * ibmvtpm_send_crq() - Send a CRQ request |
---|
59 | 53 | * |
---|
60 | 54 | * @vdev: vio device struct |
---|
61 | 55 | * @valid: Valid field |
---|
.. | .. |
---|
112 | 106 | { |
---|
113 | 107 | struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); |
---|
114 | 108 | u16 len; |
---|
115 | | - int sig; |
---|
116 | 109 | |
---|
117 | 110 | if (!ibmvtpm->rtce_buf) { |
---|
118 | 111 | dev_err(ibmvtpm->dev, "ibmvtpm device is not ready\n"); |
---|
119 | 112 | return 0; |
---|
120 | 113 | } |
---|
121 | | - |
---|
122 | | - sig = wait_event_interruptible(ibmvtpm->wq, !ibmvtpm->tpm_processing_cmd); |
---|
123 | | - if (sig) |
---|
124 | | - return -EINTR; |
---|
125 | 114 | |
---|
126 | 115 | len = ibmvtpm->res_len; |
---|
127 | 116 | |
---|
.. | .. |
---|
243 | 232 | * set the processing flag before the Hcall, since we may get the |
---|
244 | 233 | * result (interrupt) before even being able to check rc. |
---|
245 | 234 | */ |
---|
246 | | - ibmvtpm->tpm_processing_cmd = true; |
---|
| 235 | + ibmvtpm->tpm_processing_cmd = 1; |
---|
247 | 236 | |
---|
248 | 237 | again: |
---|
249 | 238 | rc = ibmvtpm_send_crq(ibmvtpm->vdev, |
---|
.. | .. |
---|
261 | 250 | goto again; |
---|
262 | 251 | } |
---|
263 | 252 | dev_err(ibmvtpm->dev, "tpm_ibmvtpm_send failed rc=%d\n", rc); |
---|
264 | | - ibmvtpm->tpm_processing_cmd = false; |
---|
| 253 | + ibmvtpm->tpm_processing_cmd = 0; |
---|
265 | 254 | } |
---|
266 | 255 | |
---|
267 | 256 | spin_unlock(&ibmvtpm->rtce_lock); |
---|
.. | .. |
---|
275 | 264 | |
---|
276 | 265 | static u8 tpm_ibmvtpm_status(struct tpm_chip *chip) |
---|
277 | 266 | { |
---|
278 | | - return 0; |
---|
| 267 | + struct ibmvtpm_dev *ibmvtpm = dev_get_drvdata(&chip->dev); |
---|
| 268 | + |
---|
| 269 | + return ibmvtpm->tpm_processing_cmd; |
---|
279 | 270 | } |
---|
280 | 271 | |
---|
281 | 272 | /** |
---|
.. | .. |
---|
465 | 456 | .send = tpm_ibmvtpm_send, |
---|
466 | 457 | .cancel = tpm_ibmvtpm_cancel, |
---|
467 | 458 | .status = tpm_ibmvtpm_status, |
---|
468 | | - .req_complete_mask = 0, |
---|
| 459 | + .req_complete_mask = 1, |
---|
469 | 460 | .req_complete_val = 0, |
---|
470 | 461 | .req_canceled = tpm_ibmvtpm_req_canceled, |
---|
471 | 462 | }; |
---|
.. | .. |
---|
558 | 549 | case VTPM_TPM_COMMAND_RES: |
---|
559 | 550 | /* len of the data in rtce buffer */ |
---|
560 | 551 | ibmvtpm->res_len = be16_to_cpu(crq->len); |
---|
561 | | - ibmvtpm->tpm_processing_cmd = false; |
---|
| 552 | + ibmvtpm->tpm_processing_cmd = 0; |
---|
562 | 553 | wake_up_interruptible(&ibmvtpm->wq); |
---|
563 | 554 | return; |
---|
564 | 555 | default: |
---|
.. | .. |
---|
692 | 683 | if (!wait_event_timeout(ibmvtpm->crq_queue.wq, |
---|
693 | 684 | ibmvtpm->rtce_buf != NULL, |
---|
694 | 685 | HZ)) { |
---|
| 686 | + rc = -ENODEV; |
---|
695 | 687 | dev_err(dev, "CRQ response timed out\n"); |
---|
696 | 688 | goto init_irq_cleanup; |
---|
697 | 689 | } |
---|
698 | 690 | |
---|
| 691 | + |
---|
| 692 | + if (!strcmp(id->compat, "IBM,vtpm20")) |
---|
| 693 | + chip->flags |= TPM_CHIP_FLAG_TPM2; |
---|
| 694 | + |
---|
| 695 | + rc = tpm_get_timeouts(chip); |
---|
| 696 | + if (rc) |
---|
| 697 | + goto init_irq_cleanup; |
---|
| 698 | + |
---|
| 699 | + if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
---|
| 700 | + rc = tpm2_get_cc_attrs_tbl(chip); |
---|
| 701 | + if (rc) |
---|
| 702 | + goto init_irq_cleanup; |
---|
| 703 | + } |
---|
| 704 | + |
---|
699 | 705 | return tpm_chip_register(chip); |
---|
700 | 706 | init_irq_cleanup: |
---|
701 | 707 | do { |
---|