|
29 | 29 | #include <linux/mutex.h> |
30 | 30 | #include <linux/spinlock.h> |
31 | 31 | #include <linux/freezer.h> |
| 32 | +#include <linux/reboot.h> |
32 | 33 |
|
33 | 34 | #include "tpm.h" |
34 | 35 | #include "tpm_eventlog.h" |
@@ -1465,10 +1466,22 @@ static void tpm_dev_release(struct device *dev) |
1465 | 1466 | tpm_dev_vendor_release(chip); |
1466 | 1467 |
|
1467 | 1468 | chip->release(dev); |
| 1469 | + unregister_reboot_notifier(&chip->shutdown_nb); |
1468 | 1470 | kfree(chip); |
1469 | 1471 | } |
1470 | 1472 | EXPORT_SYMBOL_GPL(tpm_dev_release); |
1471 | 1473 |
|
| 1474 | +static int tpm_shutdown_notify(struct notifier_block *nb, |
| 1475 | + unsigned long unused, void *unused2) |
| 1476 | +{ |
| 1477 | + struct tpm_chip *chip = container_of(nb, struct tpm_chip, shutdown_nb); |
| 1478 | + dev_dbg(chip->dev, "acquiring shutdown lock\n"); |
| 1479 | + mutex_lock(&chip->tpm_mutex); |
| 1480 | + dev_dbg(chip->dev, "acquired shutdown lock\n"); |
| 1481 | + return NOTIFY_DONE; |
| 1482 | +} |
| 1483 | + |
| 1484 | + |
1472 | 1485 | /* |
1473 | 1486 | * Called from tpm_<specific>.c probe function only for devices |
1474 | 1487 | * the driver has determined it should claim. Prior to calling |
@@ -1549,6 +1562,13 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, |
1549 | 1562 | list_add_rcu(&chip->list, &tpm_chip_list); |
1550 | 1563 | spin_unlock(&driver_lock); |
1551 | 1564 |
|
| 1565 | + /* INFINEON TPM WORKAROUND: Register shutdown callback that ensures we |
| 1566 | + * don't shut down in the middle of a TPM command, or we may trigger |
| 1567 | + * nasty defensive timeouts at the next boot. |
| 1568 | + */ |
| 1569 | + chip->shutdown_nb.notifier_call = tpm_shutdown_notify; |
| 1570 | + register_reboot_notifier(&chip->shutdown_nb); |
| 1571 | + |
1552 | 1572 | return chip; |
1553 | 1573 |
|
1554 | 1574 | put_device: |
|
0 commit comments