diff options
| -rw-r--r-- | drivers/char/tpm/tpm-interface.c | 158 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm.h | 32 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm2-cmd.c | 62 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_crb.c | 113 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_tis_core.c | 4 | ||||
| -rw-r--r-- | include/linux/tpm.h | 2 |
6 files changed, 250 insertions, 121 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 9e80a953d693..c43a9e28995e 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
| @@ -369,20 +369,40 @@ err_len: | |||
| 369 | return -EINVAL; | 369 | return -EINVAL; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | /** | 372 | static int tpm_request_locality(struct tpm_chip *chip) |
| 373 | * tmp_transmit - Internal kernel interface to transmit TPM commands. | 373 | { |
| 374 | * | 374 | int rc; |
| 375 | * @chip: TPM chip to use | 375 | |
| 376 | * @buf: TPM command buffer | 376 | if (!chip->ops->request_locality) |
| 377 | * @bufsiz: length of the TPM command buffer | 377 | return 0; |
| 378 | * @flags: tpm transmit flags - bitmap | 378 | |
| 379 | * | 379 | rc = chip->ops->request_locality(chip, 0); |
| 380 | * Return: | 380 | if (rc < 0) |
| 381 | * 0 when the operation is successful. | 381 | return rc; |
| 382 | * A negative number for system errors (errno). | 382 | |
| 383 | */ | 383 | chip->locality = rc; |
| 384 | ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | 384 | |
| 385 | u8 *buf, size_t bufsiz, unsigned int flags) | 385 | return 0; |
| 386 | } | ||
| 387 | |||
| 388 | static void tpm_relinquish_locality(struct tpm_chip *chip) | ||
| 389 | { | ||
| 390 | int rc; | ||
| 391 | |||
| 392 | if (!chip->ops->relinquish_locality) | ||
| 393 | return; | ||
| 394 | |||
| 395 | rc = chip->ops->relinquish_locality(chip, chip->locality); | ||
| 396 | if (rc) | ||
| 397 | dev_err(&chip->dev, "%s: : error %d\n", __func__, rc); | ||
| 398 | |||
| 399 | chip->locality = -1; | ||
| 400 | } | ||
| 401 | |||
| 402 | static ssize_t tpm_try_transmit(struct tpm_chip *chip, | ||
| 403 | struct tpm_space *space, | ||
| 404 | u8 *buf, size_t bufsiz, | ||
| 405 | unsigned int flags) | ||
| 386 | { | 406 | { |
| 387 | struct tpm_output_header *header = (void *)buf; | 407 | struct tpm_output_header *header = (void *)buf; |
| 388 | int rc; | 408 | int rc; |
| @@ -422,8 +442,6 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | |||
| 422 | if (!(flags & TPM_TRANSMIT_UNLOCKED)) | 442 | if (!(flags & TPM_TRANSMIT_UNLOCKED)) |
| 423 | mutex_lock(&chip->tpm_mutex); | 443 | mutex_lock(&chip->tpm_mutex); |
| 424 | 444 | ||
| 425 | if (chip->dev.parent) | ||
| 426 | pm_runtime_get_sync(chip->dev.parent); | ||
| 427 | 445 | ||
| 428 | if (chip->ops->clk_enable != NULL) | 446 | if (chip->ops->clk_enable != NULL) |
| 429 | chip->ops->clk_enable(chip, true); | 447 | chip->ops->clk_enable(chip, true); |
| @@ -431,19 +449,20 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | |||
| 431 | /* Store the decision as chip->locality will be changed. */ | 449 | /* Store the decision as chip->locality will be changed. */ |
| 432 | need_locality = chip->locality == -1; | 450 | need_locality = chip->locality == -1; |
| 433 | 451 | ||
| 434 | if (!(flags & TPM_TRANSMIT_RAW) && | 452 | if (!(flags & TPM_TRANSMIT_RAW) && need_locality) { |
| 435 | need_locality && chip->ops->request_locality) { | 453 | rc = tpm_request_locality(chip); |
| 436 | rc = chip->ops->request_locality(chip, 0); | ||
| 437 | if (rc < 0) | 454 | if (rc < 0) |
| 438 | goto out_no_locality; | 455 | goto out_no_locality; |
| 439 | chip->locality = rc; | ||
| 440 | } | 456 | } |
| 441 | 457 | ||
| 458 | if (chip->dev.parent) | ||
| 459 | pm_runtime_get_sync(chip->dev.parent); | ||
| 460 | |||
| 442 | rc = tpm2_prepare_space(chip, space, ordinal, buf); | 461 | rc = tpm2_prepare_space(chip, space, ordinal, buf); |
| 443 | if (rc) | 462 | if (rc) |
| 444 | goto out; | 463 | goto out; |
| 445 | 464 | ||
| 446 | rc = chip->ops->send(chip, (u8 *) buf, count); | 465 | rc = chip->ops->send(chip, buf, count); |
| 447 | if (rc < 0) { | 466 | if (rc < 0) { |
| 448 | if (rc != -EPIPE) | 467 | if (rc != -EPIPE) |
| 449 | dev_err(&chip->dev, | 468 | dev_err(&chip->dev, |
| @@ -480,7 +499,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | |||
| 480 | goto out; | 499 | goto out; |
| 481 | 500 | ||
| 482 | out_recv: | 501 | out_recv: |
| 483 | len = chip->ops->recv(chip, (u8 *) buf, bufsiz); | 502 | len = chip->ops->recv(chip, buf, bufsiz); |
| 484 | if (len < 0) { | 503 | if (len < 0) { |
| 485 | rc = len; | 504 | rc = len; |
| 486 | dev_err(&chip->dev, | 505 | dev_err(&chip->dev, |
| @@ -499,27 +518,95 @@ out_recv: | |||
| 499 | rc = tpm2_commit_space(chip, space, ordinal, buf, &len); | 518 | rc = tpm2_commit_space(chip, space, ordinal, buf, &len); |
| 500 | 519 | ||
| 501 | out: | 520 | out: |
| 502 | if (need_locality && chip->ops->relinquish_locality) { | 521 | if (chip->dev.parent) |
| 503 | chip->ops->relinquish_locality(chip, chip->locality); | 522 | pm_runtime_put_sync(chip->dev.parent); |
| 504 | chip->locality = -1; | 523 | |
| 505 | } | 524 | if (need_locality) |
| 525 | tpm_relinquish_locality(chip); | ||
| 526 | |||
| 506 | out_no_locality: | 527 | out_no_locality: |
| 507 | if (chip->ops->clk_enable != NULL) | 528 | if (chip->ops->clk_enable != NULL) |
| 508 | chip->ops->clk_enable(chip, false); | 529 | chip->ops->clk_enable(chip, false); |
| 509 | 530 | ||
| 510 | if (chip->dev.parent) | ||
| 511 | pm_runtime_put_sync(chip->dev.parent); | ||
| 512 | |||
| 513 | if (!(flags & TPM_TRANSMIT_UNLOCKED)) | 531 | if (!(flags & TPM_TRANSMIT_UNLOCKED)) |
| 514 | mutex_unlock(&chip->tpm_mutex); | 532 | mutex_unlock(&chip->tpm_mutex); |
| 515 | return rc ? rc : len; | 533 | return rc ? rc : len; |
| 516 | } | 534 | } |
| 517 | 535 | ||
| 518 | /** | 536 | /** |
| 519 | * tmp_transmit_cmd - send a tpm command to the device | 537 | * tpm_transmit - Internal kernel interface to transmit TPM commands. |
| 538 | * | ||
| 539 | * @chip: TPM chip to use | ||
| 540 | * @space: tpm space | ||
| 541 | * @buf: TPM command buffer | ||
| 542 | * @bufsiz: length of the TPM command buffer | ||
| 543 | * @flags: tpm transmit flags - bitmap | ||
| 544 | * | ||
| 545 | * A wrapper around tpm_try_transmit that handles TPM2_RC_RETRY | ||
| 546 | * returns from the TPM and retransmits the command after a delay up | ||
| 547 | * to a maximum wait of TPM2_DURATION_LONG. | ||
| 548 | * | ||
| 549 | * Note: TPM1 never returns TPM2_RC_RETRY so the retry logic is TPM2 | ||
| 550 | * only | ||
| 551 | * | ||
| 552 | * Return: | ||
| 553 | * the length of the return when the operation is successful. | ||
| 554 | * A negative number for system errors (errno). | ||
| 555 | */ | ||
| 556 | ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | ||
| 557 | u8 *buf, size_t bufsiz, unsigned int flags) | ||
| 558 | { | ||
| 559 | struct tpm_output_header *header = (struct tpm_output_header *)buf; | ||
| 560 | /* space for header and handles */ | ||
| 561 | u8 save[TPM_HEADER_SIZE + 3*sizeof(u32)]; | ||
| 562 | unsigned int delay_msec = TPM2_DURATION_SHORT; | ||
| 563 | u32 rc = 0; | ||
| 564 | ssize_t ret; | ||
| 565 | const size_t save_size = min(space ? sizeof(save) : TPM_HEADER_SIZE, | ||
| 566 | bufsiz); | ||
| 567 | /* the command code is where the return code will be */ | ||
| 568 | u32 cc = be32_to_cpu(header->return_code); | ||
| 569 | |||
| 570 | /* | ||
| 571 | * Subtlety here: if we have a space, the handles will be | ||
| 572 | * transformed, so when we restore the header we also have to | ||
| 573 | * restore the handles. | ||
| 574 | */ | ||
| 575 | memcpy(save, buf, save_size); | ||
| 576 | |||
| 577 | for (;;) { | ||
| 578 | ret = tpm_try_transmit(chip, space, buf, bufsiz, flags); | ||
| 579 | if (ret < 0) | ||
| 580 | break; | ||
| 581 | rc = be32_to_cpu(header->return_code); | ||
| 582 | if (rc != TPM2_RC_RETRY && rc != TPM2_RC_TESTING) | ||
| 583 | break; | ||
| 584 | /* | ||
| 585 | * return immediately if self test returns test | ||
| 586 | * still running to shorten boot time. | ||
| 587 | */ | ||
| 588 | if (rc == TPM2_RC_TESTING && cc == TPM2_CC_SELF_TEST) | ||
| 589 | break; | ||
| 590 | delay_msec *= 2; | ||
| 591 | if (delay_msec > TPM2_DURATION_LONG) { | ||
| 592 | if (rc == TPM2_RC_RETRY) | ||
| 593 | dev_err(&chip->dev, "in retry loop\n"); | ||
| 594 | else | ||
| 595 | dev_err(&chip->dev, | ||
| 596 | "self test is still running\n"); | ||
| 597 | break; | ||
| 598 | } | ||
| 599 | tpm_msleep(delay_msec); | ||
| 600 | memcpy(buf, save, save_size); | ||
| 601 | } | ||
| 602 | return ret; | ||
| 603 | } | ||
| 604 | /** | ||
| 605 | * tpm_transmit_cmd - send a tpm command to the device | ||
| 520 | * The function extracts tpm out header return code | 606 | * The function extracts tpm out header return code |
| 521 | * | 607 | * |
| 522 | * @chip: TPM chip to use | 608 | * @chip: TPM chip to use |
| 609 | * @space: tpm space | ||
| 523 | * @buf: TPM command buffer | 610 | * @buf: TPM command buffer |
| 524 | * @bufsiz: length of the buffer | 611 | * @bufsiz: length of the buffer |
| 525 | * @min_rsp_body_length: minimum expected length of response body | 612 | * @min_rsp_body_length: minimum expected length of response body |
| @@ -532,7 +619,7 @@ out_no_locality: | |||
| 532 | * A positive number for a TPM error. | 619 | * A positive number for a TPM error. |
| 533 | */ | 620 | */ |
| 534 | ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, | 621 | ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, |
| 535 | const void *buf, size_t bufsiz, | 622 | void *buf, size_t bufsiz, |
| 536 | size_t min_rsp_body_length, unsigned int flags, | 623 | size_t min_rsp_body_length, unsigned int flags, |
| 537 | const char *desc) | 624 | const char *desc) |
| 538 | { | 625 | { |
| @@ -540,7 +627,7 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, | |||
| 540 | int err; | 627 | int err; |
| 541 | ssize_t len; | 628 | ssize_t len; |
| 542 | 629 | ||
| 543 | len = tpm_transmit(chip, space, (u8 *)buf, bufsiz, flags); | 630 | len = tpm_transmit(chip, space, buf, bufsiz, flags); |
| 544 | if (len < 0) | 631 | if (len < 0) |
| 545 | return len; | 632 | return len; |
| 546 | 633 | ||
| @@ -666,6 +753,8 @@ int tpm_get_timeouts(struct tpm_chip *chip) | |||
| 666 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); | 753 | msecs_to_jiffies(TPM2_DURATION_MEDIUM); |
| 667 | chip->duration[TPM_LONG] = | 754 | chip->duration[TPM_LONG] = |
| 668 | msecs_to_jiffies(TPM2_DURATION_LONG); | 755 | msecs_to_jiffies(TPM2_DURATION_LONG); |
| 756 | chip->duration[TPM_LONG_LONG] = | ||
| 757 | msecs_to_jiffies(TPM2_DURATION_LONG_LONG); | ||
| 669 | 758 | ||
| 670 | chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS; | 759 | chip->flags |= TPM_CHIP_FLAG_HAVE_TIMEOUTS; |
| 671 | return 0; | 760 | return 0; |
| @@ -754,6 +843,7 @@ int tpm_get_timeouts(struct tpm_chip *chip) | |||
| 754 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_medium)); | 843 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_medium)); |
| 755 | chip->duration[TPM_LONG] = | 844 | chip->duration[TPM_LONG] = |
| 756 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_long)); | 845 | usecs_to_jiffies(be32_to_cpu(cap.duration.tpm_long)); |
| 846 | chip->duration[TPM_LONG_LONG] = 0; /* not used under 1.2 */ | ||
| 757 | 847 | ||
| 758 | /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above | 848 | /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above |
| 759 | * value wrong and apparently reports msecs rather than usecs. So we | 849 | * value wrong and apparently reports msecs rather than usecs. So we |
| @@ -969,6 +1059,10 @@ int tpm_do_selftest(struct tpm_chip *chip) | |||
| 969 | loops = jiffies_to_msecs(duration) / delay_msec; | 1059 | loops = jiffies_to_msecs(duration) / delay_msec; |
| 970 | 1060 | ||
| 971 | rc = tpm_continue_selftest(chip); | 1061 | rc = tpm_continue_selftest(chip); |
| 1062 | if (rc == TPM_ERR_INVALID_POSTINIT) { | ||
| 1063 | chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED; | ||
| 1064 | dev_info(&chip->dev, "TPM not ready (%d)\n", rc); | ||
| 1065 | } | ||
| 972 | /* This may fail if there was no TPM driver during a suspend/resume | 1066 | /* This may fail if there was no TPM driver during a suspend/resume |
| 973 | * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST) | 1067 | * cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST) |
| 974 | */ | 1068 | */ |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index f895fba4e20d..7f2d0f489e9c 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
| @@ -67,7 +67,9 @@ enum tpm_duration { | |||
| 67 | TPM_SHORT = 0, | 67 | TPM_SHORT = 0, |
| 68 | TPM_MEDIUM = 1, | 68 | TPM_MEDIUM = 1, |
| 69 | TPM_LONG = 2, | 69 | TPM_LONG = 2, |
| 70 | TPM_LONG_LONG = 3, | ||
| 70 | TPM_UNDEFINED, | 71 | TPM_UNDEFINED, |
| 72 | TPM_NUM_DURATIONS = TPM_UNDEFINED, | ||
| 71 | }; | 73 | }; |
| 72 | 74 | ||
| 73 | #define TPM_WARN_RETRY 0x800 | 75 | #define TPM_WARN_RETRY 0x800 |
| @@ -79,15 +81,20 @@ enum tpm_duration { | |||
| 79 | #define TPM_HEADER_SIZE 10 | 81 | #define TPM_HEADER_SIZE 10 |
| 80 | 82 | ||
| 81 | enum tpm2_const { | 83 | enum tpm2_const { |
| 82 | TPM2_PLATFORM_PCR = 24, | 84 | TPM2_PLATFORM_PCR = 24, |
| 83 | TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), | 85 | TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8), |
| 84 | TPM2_TIMEOUT_A = 750, | 86 | }; |
| 85 | TPM2_TIMEOUT_B = 2000, | 87 | |
| 86 | TPM2_TIMEOUT_C = 200, | 88 | enum tpm2_timeouts { |
| 87 | TPM2_TIMEOUT_D = 30, | 89 | TPM2_TIMEOUT_A = 750, |
| 88 | TPM2_DURATION_SHORT = 20, | 90 | TPM2_TIMEOUT_B = 2000, |
| 89 | TPM2_DURATION_MEDIUM = 750, | 91 | TPM2_TIMEOUT_C = 200, |
| 90 | TPM2_DURATION_LONG = 2000, | 92 | TPM2_TIMEOUT_D = 30, |
| 93 | TPM2_DURATION_SHORT = 20, | ||
| 94 | TPM2_DURATION_MEDIUM = 750, | ||
| 95 | TPM2_DURATION_LONG = 2000, | ||
| 96 | TPM2_DURATION_LONG_LONG = 300000, | ||
| 97 | TPM2_DURATION_DEFAULT = 120000, | ||
| 91 | }; | 98 | }; |
| 92 | 99 | ||
| 93 | enum tpm2_structures { | 100 | enum tpm2_structures { |
| @@ -104,10 +111,12 @@ enum tpm2_return_codes { | |||
| 104 | TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ | 111 | TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ |
| 105 | TPM2_RC_HANDLE = 0x008B, | 112 | TPM2_RC_HANDLE = 0x008B, |
| 106 | TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ | 113 | TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ |
| 114 | TPM2_RC_FAILURE = 0x0101, | ||
| 107 | TPM2_RC_DISABLED = 0x0120, | 115 | TPM2_RC_DISABLED = 0x0120, |
| 108 | TPM2_RC_COMMAND_CODE = 0x0143, | 116 | TPM2_RC_COMMAND_CODE = 0x0143, |
| 109 | TPM2_RC_TESTING = 0x090A, /* RC_WARN */ | 117 | TPM2_RC_TESTING = 0x090A, /* RC_WARN */ |
| 110 | TPM2_RC_REFERENCE_H0 = 0x0910, | 118 | TPM2_RC_REFERENCE_H0 = 0x0910, |
| 119 | TPM2_RC_RETRY = 0x0922, | ||
| 111 | }; | 120 | }; |
| 112 | 121 | ||
| 113 | enum tpm2_algorithms { | 122 | enum tpm2_algorithms { |
| @@ -123,6 +132,7 @@ enum tpm2_algorithms { | |||
| 123 | 132 | ||
| 124 | enum tpm2_command_codes { | 133 | enum tpm2_command_codes { |
| 125 | TPM2_CC_FIRST = 0x011F, | 134 | TPM2_CC_FIRST = 0x011F, |
| 135 | TPM2_CC_CREATE_PRIMARY = 0x0131, | ||
| 126 | TPM2_CC_SELF_TEST = 0x0143, | 136 | TPM2_CC_SELF_TEST = 0x0143, |
| 127 | TPM2_CC_STARTUP = 0x0144, | 137 | TPM2_CC_STARTUP = 0x0144, |
| 128 | TPM2_CC_SHUTDOWN = 0x0145, | 138 | TPM2_CC_SHUTDOWN = 0x0145, |
| @@ -227,7 +237,7 @@ struct tpm_chip { | |||
| 227 | unsigned long timeout_c; /* jiffies */ | 237 | unsigned long timeout_c; /* jiffies */ |
| 228 | unsigned long timeout_d; /* jiffies */ | 238 | unsigned long timeout_d; /* jiffies */ |
| 229 | bool timeout_adjusted; | 239 | bool timeout_adjusted; |
| 230 | unsigned long duration[3]; /* jiffies */ | 240 | unsigned long duration[TPM_NUM_DURATIONS]; /* jiffies */ |
| 231 | bool duration_adjusted; | 241 | bool duration_adjusted; |
| 232 | 242 | ||
| 233 | struct dentry *bios_dir[TPM_NUM_EVENT_LOG_FILES]; | 243 | struct dentry *bios_dir[TPM_NUM_EVENT_LOG_FILES]; |
| @@ -506,7 +516,7 @@ enum tpm_transmit_flags { | |||
| 506 | ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | 516 | ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, |
| 507 | u8 *buf, size_t bufsiz, unsigned int flags); | 517 | u8 *buf, size_t bufsiz, unsigned int flags); |
| 508 | ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, | 518 | ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, |
| 509 | const void *buf, size_t bufsiz, | 519 | void *buf, size_t bufsiz, |
| 510 | size_t min_rsp_body_length, unsigned int flags, | 520 | size_t min_rsp_body_length, unsigned int flags, |
| 511 | const char *desc); | 521 | const char *desc); |
| 512 | int tpm_startup(struct tpm_chip *chip); | 522 | int tpm_startup(struct tpm_chip *chip); |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index a700f8f9ead7..96c77c8e7f40 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
| @@ -31,10 +31,6 @@ struct tpm2_startup_in { | |||
| 31 | __be16 startup_type; | 31 | __be16 startup_type; |
| 32 | } __packed; | 32 | } __packed; |
| 33 | 33 | ||
| 34 | struct tpm2_self_test_in { | ||
| 35 | u8 full_test; | ||
| 36 | } __packed; | ||
| 37 | |||
| 38 | struct tpm2_get_tpm_pt_in { | 34 | struct tpm2_get_tpm_pt_in { |
| 39 | __be32 cap_id; | 35 | __be32 cap_id; |
| 40 | __be32 property_id; | 36 | __be32 property_id; |
| @@ -60,7 +56,6 @@ struct tpm2_get_random_out { | |||
| 60 | 56 | ||
| 61 | union tpm2_cmd_params { | 57 | union tpm2_cmd_params { |
| 62 | struct tpm2_startup_in startup_in; | 58 | struct tpm2_startup_in startup_in; |
| 63 | struct tpm2_self_test_in selftest_in; | ||
| 64 | struct tpm2_get_tpm_pt_in get_tpm_pt_in; | 59 | struct tpm2_get_tpm_pt_in get_tpm_pt_in; |
| 65 | struct tpm2_get_tpm_pt_out get_tpm_pt_out; | 60 | struct tpm2_get_tpm_pt_out get_tpm_pt_out; |
| 66 | struct tpm2_get_random_in getrandom_in; | 61 | struct tpm2_get_random_in getrandom_in; |
| @@ -90,6 +85,8 @@ static struct tpm2_hash tpm2_hash_map[] = { | |||
| 90 | * of time the chip could take to return the result. The values | 85 | * of time the chip could take to return the result. The values |
| 91 | * of the SHORT, MEDIUM, and LONG durations are taken from the | 86 | * of the SHORT, MEDIUM, and LONG durations are taken from the |
| 92 | * PC Client Profile (PTP) specification. | 87 | * PC Client Profile (PTP) specification. |
| 88 | * LONG_LONG is for commands that generates keys which empirically | ||
| 89 | * takes longer time on some systems. | ||
| 93 | */ | 90 | */ |
| 94 | static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | 91 | static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { |
| 95 | TPM_UNDEFINED, /* 11F */ | 92 | TPM_UNDEFINED, /* 11F */ |
| @@ -110,7 +107,7 @@ static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | |||
| 110 | TPM_UNDEFINED, /* 12e */ | 107 | TPM_UNDEFINED, /* 12e */ |
| 111 | TPM_UNDEFINED, /* 12f */ | 108 | TPM_UNDEFINED, /* 12f */ |
| 112 | TPM_UNDEFINED, /* 130 */ | 109 | TPM_UNDEFINED, /* 130 */ |
| 113 | TPM_UNDEFINED, /* 131 */ | 110 | TPM_LONG_LONG, /* 131 */ |
| 114 | TPM_UNDEFINED, /* 132 */ | 111 | TPM_UNDEFINED, /* 132 */ |
| 115 | TPM_UNDEFINED, /* 133 */ | 112 | TPM_UNDEFINED, /* 133 */ |
| 116 | TPM_UNDEFINED, /* 134 */ | 113 | TPM_UNDEFINED, /* 134 */ |
| @@ -144,7 +141,7 @@ static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = { | |||
| 144 | TPM_UNDEFINED, /* 150 */ | 141 | TPM_UNDEFINED, /* 150 */ |
| 145 | TPM_UNDEFINED, /* 151 */ | 142 | TPM_UNDEFINED, /* 151 */ |
| 146 | TPM_UNDEFINED, /* 152 */ | 143 | TPM_UNDEFINED, /* 152 */ |
| 147 | TPM_UNDEFINED, /* 153 */ | 144 | TPM_LONG_LONG, /* 153 */ |
| 148 | TPM_UNDEFINED, /* 154 */ | 145 | TPM_UNDEFINED, /* 154 */ |
| 149 | TPM_UNDEFINED, /* 155 */ | 146 | TPM_UNDEFINED, /* 155 */ |
| 150 | TPM_UNDEFINED, /* 156 */ | 147 | TPM_UNDEFINED, /* 156 */ |
| @@ -821,22 +818,12 @@ unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal) | |||
| 821 | duration = chip->duration[index]; | 818 | duration = chip->duration[index]; |
| 822 | 819 | ||
| 823 | if (duration <= 0) | 820 | if (duration <= 0) |
| 824 | duration = 2 * 60 * HZ; | 821 | duration = msecs_to_jiffies(TPM2_DURATION_DEFAULT); |
| 825 | 822 | ||
| 826 | return duration; | 823 | return duration; |
| 827 | } | 824 | } |
| 828 | EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration); | 825 | EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration); |
| 829 | 826 | ||
| 830 | #define TPM2_SELF_TEST_IN_SIZE \ | ||
| 831 | (sizeof(struct tpm_input_header) + \ | ||
| 832 | sizeof(struct tpm2_self_test_in)) | ||
| 833 | |||
| 834 | static const struct tpm_input_header tpm2_selftest_header = { | ||
| 835 | .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS), | ||
| 836 | .length = cpu_to_be32(TPM2_SELF_TEST_IN_SIZE), | ||
| 837 | .ordinal = cpu_to_be32(TPM2_CC_SELF_TEST) | ||
| 838 | }; | ||
| 839 | |||
| 840 | /** | 827 | /** |
| 841 | * tpm2_do_selftest() - ensure that all self tests have passed | 828 | * tpm2_do_selftest() - ensure that all self tests have passed |
| 842 | * | 829 | * |
| @@ -852,27 +839,24 @@ static const struct tpm_input_header tpm2_selftest_header = { | |||
| 852 | */ | 839 | */ |
| 853 | static int tpm2_do_selftest(struct tpm_chip *chip) | 840 | static int tpm2_do_selftest(struct tpm_chip *chip) |
| 854 | { | 841 | { |
| 842 | struct tpm_buf buf; | ||
| 843 | int full; | ||
| 855 | int rc; | 844 | int rc; |
| 856 | unsigned int delay_msec = 10; | ||
| 857 | long duration; | ||
| 858 | struct tpm2_cmd cmd; | ||
| 859 | 845 | ||
| 860 | duration = jiffies_to_msecs( | 846 | for (full = 0; full < 2; full++) { |
| 861 | tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST)); | 847 | rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SELF_TEST); |
| 862 | 848 | if (rc) | |
| 863 | while (1) { | 849 | return rc; |
| 864 | cmd.header.in = tpm2_selftest_header; | ||
| 865 | cmd.params.selftest_in.full_test = 0; | ||
| 866 | |||
| 867 | rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE, | ||
| 868 | 0, 0, "continue selftest"); | ||
| 869 | 850 | ||
| 870 | if (rc != TPM2_RC_TESTING || delay_msec >= duration) | 851 | tpm_buf_append_u8(&buf, full); |
| 871 | break; | 852 | rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, |
| 853 | "attempting the self test"); | ||
| 854 | tpm_buf_destroy(&buf); | ||
| 872 | 855 | ||
| 873 | /* wait longer than before */ | 856 | if (rc == TPM2_RC_TESTING) |
| 874 | delay_msec *= 2; | 857 | rc = TPM2_RC_SUCCESS; |
| 875 | tpm_msleep(delay_msec); | 858 | if (rc == TPM2_RC_INITIALIZE || rc == TPM2_RC_SUCCESS) |
| 859 | return rc; | ||
| 876 | } | 860 | } |
| 877 | 861 | ||
| 878 | return rc; | 862 | return rc; |
| @@ -1058,10 +1042,8 @@ int tpm2_auto_startup(struct tpm_chip *chip) | |||
| 1058 | goto out; | 1042 | goto out; |
| 1059 | 1043 | ||
| 1060 | rc = tpm2_do_selftest(chip); | 1044 | rc = tpm2_do_selftest(chip); |
| 1061 | if (rc != 0 && rc != TPM2_RC_INITIALIZE) { | 1045 | if (rc && rc != TPM2_RC_INITIALIZE) |
| 1062 | dev_err(&chip->dev, "TPM self test failed\n"); | ||
| 1063 | goto out; | 1046 | goto out; |
| 1064 | } | ||
| 1065 | 1047 | ||
| 1066 | if (rc == TPM2_RC_INITIALIZE) { | 1048 | if (rc == TPM2_RC_INITIALIZE) { |
| 1067 | rc = tpm_startup(chip); | 1049 | rc = tpm_startup(chip); |
| @@ -1069,10 +1051,8 @@ int tpm2_auto_startup(struct tpm_chip *chip) | |||
| 1069 | goto out; | 1051 | goto out; |
| 1070 | 1052 | ||
| 1071 | rc = tpm2_do_selftest(chip); | 1053 | rc = tpm2_do_selftest(chip); |
| 1072 | if (rc) { | 1054 | if (rc) |
| 1073 | dev_err(&chip->dev, "TPM self test failed\n"); | ||
| 1074 | goto out; | 1055 | goto out; |
| 1075 | } | ||
| 1076 | } | 1056 | } |
| 1077 | 1057 | ||
| 1078 | rc = tpm2_get_pcr_allocation(chip); | 1058 | rc = tpm2_get_pcr_allocation(chip); |
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index 7b3c2a8aa9de..7f78482cd157 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c | |||
| @@ -112,6 +112,25 @@ struct tpm2_crb_smc { | |||
| 112 | u32 smc_func_id; | 112 | u32 smc_func_id; |
| 113 | }; | 113 | }; |
| 114 | 114 | ||
| 115 | static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, | ||
| 116 | unsigned long timeout) | ||
| 117 | { | ||
| 118 | ktime_t start; | ||
| 119 | ktime_t stop; | ||
| 120 | |||
| 121 | start = ktime_get(); | ||
| 122 | stop = ktime_add(start, ms_to_ktime(timeout)); | ||
| 123 | |||
| 124 | do { | ||
| 125 | if ((ioread32(reg) & mask) == value) | ||
| 126 | return true; | ||
| 127 | |||
| 128 | usleep_range(50, 100); | ||
| 129 | } while (ktime_before(ktime_get(), stop)); | ||
| 130 | |||
| 131 | return ((ioread32(reg) & mask) == value); | ||
| 132 | } | ||
| 133 | |||
| 115 | /** | 134 | /** |
| 116 | * crb_go_idle - request tpm crb device to go the idle state | 135 | * crb_go_idle - request tpm crb device to go the idle state |
| 117 | * | 136 | * |
| @@ -128,7 +147,7 @@ struct tpm2_crb_smc { | |||
| 128 | * | 147 | * |
| 129 | * Return: 0 always | 148 | * Return: 0 always |
| 130 | */ | 149 | */ |
| 131 | static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv) | 150 | static int crb_go_idle(struct device *dev, struct crb_priv *priv) |
| 132 | { | 151 | { |
| 133 | if ((priv->sm == ACPI_TPM2_START_METHOD) || | 152 | if ((priv->sm == ACPI_TPM2_START_METHOD) || |
| 134 | (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || | 153 | (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || |
| @@ -136,30 +155,17 @@ static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv) | |||
| 136 | return 0; | 155 | return 0; |
| 137 | 156 | ||
| 138 | iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); | 157 | iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); |
| 139 | /* we don't really care when this settles */ | ||
| 140 | 158 | ||
| 159 | if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req, | ||
| 160 | CRB_CTRL_REQ_GO_IDLE/* mask */, | ||
| 161 | 0, /* value */ | ||
| 162 | TPM2_TIMEOUT_C)) { | ||
| 163 | dev_warn(dev, "goIdle timed out\n"); | ||
| 164 | return -ETIME; | ||
| 165 | } | ||
| 141 | return 0; | 166 | return 0; |
| 142 | } | 167 | } |
| 143 | 168 | ||
| 144 | static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, | ||
| 145 | unsigned long timeout) | ||
| 146 | { | ||
| 147 | ktime_t start; | ||
| 148 | ktime_t stop; | ||
| 149 | |||
| 150 | start = ktime_get(); | ||
| 151 | stop = ktime_add(start, ms_to_ktime(timeout)); | ||
| 152 | |||
| 153 | do { | ||
| 154 | if ((ioread32(reg) & mask) == value) | ||
| 155 | return true; | ||
| 156 | |||
| 157 | usleep_range(50, 100); | ||
| 158 | } while (ktime_before(ktime_get(), stop)); | ||
| 159 | |||
| 160 | return false; | ||
| 161 | } | ||
| 162 | |||
| 163 | /** | 169 | /** |
| 164 | * crb_cmd_ready - request tpm crb device to enter ready state | 170 | * crb_cmd_ready - request tpm crb device to enter ready state |
| 165 | * | 171 | * |
| @@ -175,8 +181,7 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, | |||
| 175 | * | 181 | * |
| 176 | * Return: 0 on success -ETIME on timeout; | 182 | * Return: 0 on success -ETIME on timeout; |
| 177 | */ | 183 | */ |
| 178 | static int __maybe_unused crb_cmd_ready(struct device *dev, | 184 | static int crb_cmd_ready(struct device *dev, struct crb_priv *priv) |
| 179 | struct crb_priv *priv) | ||
| 180 | { | 185 | { |
| 181 | if ((priv->sm == ACPI_TPM2_START_METHOD) || | 186 | if ((priv->sm == ACPI_TPM2_START_METHOD) || |
| 182 | (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || | 187 | (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || |
| @@ -195,11 +200,11 @@ static int __maybe_unused crb_cmd_ready(struct device *dev, | |||
| 195 | return 0; | 200 | return 0; |
| 196 | } | 201 | } |
| 197 | 202 | ||
| 198 | static int crb_request_locality(struct tpm_chip *chip, int loc) | 203 | static int __crb_request_locality(struct device *dev, |
| 204 | struct crb_priv *priv, int loc) | ||
| 199 | { | 205 | { |
| 200 | struct crb_priv *priv = dev_get_drvdata(&chip->dev); | ||
| 201 | u32 value = CRB_LOC_STATE_LOC_ASSIGNED | | 206 | u32 value = CRB_LOC_STATE_LOC_ASSIGNED | |
| 202 | CRB_LOC_STATE_TPM_REG_VALID_STS; | 207 | CRB_LOC_STATE_TPM_REG_VALID_STS; |
| 203 | 208 | ||
| 204 | if (!priv->regs_h) | 209 | if (!priv->regs_h) |
| 205 | return 0; | 210 | return 0; |
| @@ -207,21 +212,45 @@ static int crb_request_locality(struct tpm_chip *chip, int loc) | |||
| 207 | iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl); | 212 | iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl); |
| 208 | if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value, | 213 | if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value, |
| 209 | TPM2_TIMEOUT_C)) { | 214 | TPM2_TIMEOUT_C)) { |
| 210 | dev_warn(&chip->dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); | 215 | dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); |
| 211 | return -ETIME; | 216 | return -ETIME; |
| 212 | } | 217 | } |
| 213 | 218 | ||
| 214 | return 0; | 219 | return 0; |
| 215 | } | 220 | } |
| 216 | 221 | ||
| 217 | static void crb_relinquish_locality(struct tpm_chip *chip, int loc) | 222 | static int crb_request_locality(struct tpm_chip *chip, int loc) |
| 218 | { | 223 | { |
| 219 | struct crb_priv *priv = dev_get_drvdata(&chip->dev); | 224 | struct crb_priv *priv = dev_get_drvdata(&chip->dev); |
| 220 | 225 | ||
| 226 | return __crb_request_locality(&chip->dev, priv, loc); | ||
| 227 | } | ||
| 228 | |||
| 229 | static int __crb_relinquish_locality(struct device *dev, | ||
| 230 | struct crb_priv *priv, int loc) | ||
| 231 | { | ||
| 232 | u32 mask = CRB_LOC_STATE_LOC_ASSIGNED | | ||
| 233 | CRB_LOC_STATE_TPM_REG_VALID_STS; | ||
| 234 | u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS; | ||
| 235 | |||
| 221 | if (!priv->regs_h) | 236 | if (!priv->regs_h) |
| 222 | return; | 237 | return 0; |
| 223 | 238 | ||
| 224 | iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); | 239 | iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); |
| 240 | if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, | ||
| 241 | TPM2_TIMEOUT_C)) { | ||
| 242 | dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); | ||
| 243 | return -ETIME; | ||
| 244 | } | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | |||
| 249 | static int crb_relinquish_locality(struct tpm_chip *chip, int loc) | ||
| 250 | { | ||
| 251 | struct crb_priv *priv = dev_get_drvdata(&chip->dev); | ||
| 252 | |||
| 253 | return __crb_relinquish_locality(&chip->dev, priv, loc); | ||
| 225 | } | 254 | } |
| 226 | 255 | ||
| 227 | static u8 crb_status(struct tpm_chip *chip) | 256 | static u8 crb_status(struct tpm_chip *chip) |
| @@ -442,6 +471,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, | |||
| 442 | u32 pa_high, pa_low; | 471 | u32 pa_high, pa_low; |
| 443 | u64 cmd_pa; | 472 | u64 cmd_pa; |
| 444 | u32 cmd_size; | 473 | u32 cmd_size; |
| 474 | __le64 __rsp_pa; | ||
| 445 | u64 rsp_pa; | 475 | u64 rsp_pa; |
| 446 | u32 rsp_size; | 476 | u32 rsp_size; |
| 447 | int ret; | 477 | int ret; |
| @@ -475,6 +505,10 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, | |||
| 475 | dev_warn(dev, FW_BUG "Bad ACPI memory layout"); | 505 | dev_warn(dev, FW_BUG "Bad ACPI memory layout"); |
| 476 | } | 506 | } |
| 477 | 507 | ||
| 508 | ret = __crb_request_locality(dev, priv, 0); | ||
| 509 | if (ret) | ||
| 510 | return ret; | ||
| 511 | |||
| 478 | priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address, | 512 | priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address, |
| 479 | sizeof(struct crb_regs_tail)); | 513 | sizeof(struct crb_regs_tail)); |
| 480 | if (IS_ERR(priv->regs_t)) | 514 | if (IS_ERR(priv->regs_t)) |
| @@ -503,8 +537,8 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, | |||
| 503 | goto out; | 537 | goto out; |
| 504 | } | 538 | } |
| 505 | 539 | ||
| 506 | memcpy_fromio(&rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8); | 540 | memcpy_fromio(&__rsp_pa, &priv->regs_t->ctrl_rsp_pa, 8); |
| 507 | rsp_pa = le64_to_cpu(rsp_pa); | 541 | rsp_pa = le64_to_cpu(__rsp_pa); |
| 508 | rsp_size = crb_fixup_cmd_size(dev, &io_res, rsp_pa, | 542 | rsp_size = crb_fixup_cmd_size(dev, &io_res, rsp_pa, |
| 509 | ioread32(&priv->regs_t->ctrl_rsp_size)); | 543 | ioread32(&priv->regs_t->ctrl_rsp_size)); |
| 510 | 544 | ||
| @@ -531,6 +565,8 @@ out: | |||
| 531 | 565 | ||
| 532 | crb_go_idle(dev, priv); | 566 | crb_go_idle(dev, priv); |
| 533 | 567 | ||
| 568 | __crb_relinquish_locality(dev, priv, 0); | ||
| 569 | |||
| 534 | return ret; | 570 | return ret; |
| 535 | } | 571 | } |
| 536 | 572 | ||
| @@ -588,10 +624,14 @@ static int crb_acpi_add(struct acpi_device *device) | |||
| 588 | chip->acpi_dev_handle = device->handle; | 624 | chip->acpi_dev_handle = device->handle; |
| 589 | chip->flags = TPM_CHIP_FLAG_TPM2; | 625 | chip->flags = TPM_CHIP_FLAG_TPM2; |
| 590 | 626 | ||
| 591 | rc = crb_cmd_ready(dev, priv); | 627 | rc = __crb_request_locality(dev, priv, 0); |
| 592 | if (rc) | 628 | if (rc) |
| 593 | return rc; | 629 | return rc; |
| 594 | 630 | ||
| 631 | rc = crb_cmd_ready(dev, priv); | ||
| 632 | if (rc) | ||
| 633 | goto out; | ||
| 634 | |||
| 595 | pm_runtime_get_noresume(dev); | 635 | pm_runtime_get_noresume(dev); |
| 596 | pm_runtime_set_active(dev); | 636 | pm_runtime_set_active(dev); |
| 597 | pm_runtime_enable(dev); | 637 | pm_runtime_enable(dev); |
| @@ -601,12 +641,15 @@ static int crb_acpi_add(struct acpi_device *device) | |||
| 601 | crb_go_idle(dev, priv); | 641 | crb_go_idle(dev, priv); |
| 602 | pm_runtime_put_noidle(dev); | 642 | pm_runtime_put_noidle(dev); |
| 603 | pm_runtime_disable(dev); | 643 | pm_runtime_disable(dev); |
| 604 | return rc; | 644 | goto out; |
| 605 | } | 645 | } |
| 606 | 646 | ||
| 607 | pm_runtime_put(dev); | 647 | pm_runtime_put_sync(dev); |
| 608 | 648 | ||
| 609 | return 0; | 649 | out: |
| 650 | __crb_relinquish_locality(dev, priv, 0); | ||
| 651 | |||
| 652 | return rc; | ||
| 610 | } | 653 | } |
| 611 | 654 | ||
| 612 | static int crb_acpi_remove(struct acpi_device *device) | 655 | static int crb_acpi_remove(struct acpi_device *device) |
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index da074e3db19b..5a1f47b43947 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c | |||
| @@ -143,11 +143,13 @@ static bool check_locality(struct tpm_chip *chip, int l) | |||
| 143 | return false; | 143 | return false; |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static void release_locality(struct tpm_chip *chip, int l) | 146 | static int release_locality(struct tpm_chip *chip, int l) |
| 147 | { | 147 | { |
| 148 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); | 148 | struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); |
| 149 | 149 | ||
| 150 | tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); | 150 | tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); |
| 151 | |||
| 152 | return 0; | ||
| 151 | } | 153 | } |
| 152 | 154 | ||
| 153 | static int request_locality(struct tpm_chip *chip, int l) | 155 | static int request_locality(struct tpm_chip *chip, int l) |
diff --git a/include/linux/tpm.h b/include/linux/tpm.h index bcdd3790e94d..06639fb6ab85 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h | |||
| @@ -44,7 +44,7 @@ struct tpm_class_ops { | |||
| 44 | bool (*update_timeouts)(struct tpm_chip *chip, | 44 | bool (*update_timeouts)(struct tpm_chip *chip, |
| 45 | unsigned long *timeout_cap); | 45 | unsigned long *timeout_cap); |
| 46 | int (*request_locality)(struct tpm_chip *chip, int loc); | 46 | int (*request_locality)(struct tpm_chip *chip, int loc); |
| 47 | void (*relinquish_locality)(struct tpm_chip *chip, int loc); | 47 | int (*relinquish_locality)(struct tpm_chip *chip, int loc); |
| 48 | void (*clk_enable)(struct tpm_chip *chip, bool value); | 48 | void (*clk_enable)(struct tpm_chip *chip, bool value); |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
