diff options
| -rw-r--r-- | drivers/char/tpm/tpm.c | 22 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm.h | 1 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_tis.c | 14 |
3 files changed, 30 insertions, 7 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 4f18f84b498a..02a495c2e068 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
| @@ -1133,23 +1133,33 @@ int tpm_pm_resume(struct device *dev) | |||
| 1133 | } | 1133 | } |
| 1134 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 1134 | EXPORT_SYMBOL_GPL(tpm_pm_resume); |
| 1135 | 1135 | ||
| 1136 | /* In case vendor provided release function, call it too.*/ | ||
| 1137 | |||
| 1138 | void tpm_dev_vendor_release(struct tpm_chip *chip) | ||
| 1139 | { | ||
| 1140 | if (chip->vendor.release) | ||
| 1141 | chip->vendor.release(chip->dev); | ||
| 1142 | |||
| 1143 | clear_bit(chip->dev_num, dev_mask); | ||
| 1144 | kfree(chip->vendor.miscdev.name); | ||
| 1145 | } | ||
| 1146 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | ||
| 1147 | |||
| 1148 | |||
| 1136 | /* | 1149 | /* |
| 1137 | * Once all references to platform device are down to 0, | 1150 | * Once all references to platform device are down to 0, |
| 1138 | * release all allocated structures. | 1151 | * release all allocated structures. |
| 1139 | * In case vendor provided release function, call it too. | ||
| 1140 | */ | 1152 | */ |
| 1141 | static void tpm_dev_release(struct device *dev) | 1153 | static void tpm_dev_release(struct device *dev) |
| 1142 | { | 1154 | { |
| 1143 | struct tpm_chip *chip = dev_get_drvdata(dev); | 1155 | struct tpm_chip *chip = dev_get_drvdata(dev); |
| 1144 | 1156 | ||
| 1145 | if (chip->vendor.release) | 1157 | tpm_dev_vendor_release(chip); |
| 1146 | chip->vendor.release(dev); | ||
| 1147 | chip->release(dev); | ||
| 1148 | 1158 | ||
| 1149 | clear_bit(chip->dev_num, dev_mask); | 1159 | chip->release(dev); |
| 1150 | kfree(chip->vendor.miscdev.name); | ||
| 1151 | kfree(chip); | 1160 | kfree(chip); |
| 1152 | } | 1161 | } |
| 1162 | EXPORT_SYMBOL_GPL(tpm_dev_release); | ||
| 1153 | 1163 | ||
| 1154 | /* | 1164 | /* |
| 1155 | * Called from tpm_<specific>.c probe function only for devices | 1165 | * Called from tpm_<specific>.c probe function only for devices |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 2756cab9aee3..8e30df4a4388 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
| @@ -132,6 +132,7 @@ extern struct tpm_chip* tpm_register_hardware(struct device *, | |||
| 132 | const struct tpm_vendor_specific *); | 132 | const struct tpm_vendor_specific *); |
| 133 | extern int tpm_open(struct inode *, struct file *); | 133 | extern int tpm_open(struct inode *, struct file *); |
| 134 | extern int tpm_release(struct inode *, struct file *); | 134 | extern int tpm_release(struct inode *, struct file *); |
| 135 | extern void tpm_dev_vendor_release(struct tpm_chip *); | ||
| 135 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | 136 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, |
| 136 | loff_t *); | 137 | loff_t *); |
| 137 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); | 138 | extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index ed1879c0dd8d..717af7ad1bdf 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
| @@ -630,12 +630,23 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { | |||
| 630 | {"", 0} /* Terminator */ | 630 | {"", 0} /* Terminator */ |
| 631 | }; | 631 | }; |
| 632 | 632 | ||
| 633 | static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) | ||
| 634 | { | ||
| 635 | struct tpm_chip *chip = pnp_get_drvdata(dev); | ||
| 636 | |||
| 637 | tpm_dev_vendor_release(chip); | ||
| 638 | |||
| 639 | kfree(chip); | ||
| 640 | } | ||
| 641 | |||
| 642 | |||
| 633 | static struct pnp_driver tis_pnp_driver = { | 643 | static struct pnp_driver tis_pnp_driver = { |
| 634 | .name = "tpm_tis", | 644 | .name = "tpm_tis", |
| 635 | .id_table = tpm_pnp_tbl, | 645 | .id_table = tpm_pnp_tbl, |
| 636 | .probe = tpm_tis_pnp_init, | 646 | .probe = tpm_tis_pnp_init, |
| 637 | .suspend = tpm_tis_pnp_suspend, | 647 | .suspend = tpm_tis_pnp_suspend, |
| 638 | .resume = tpm_tis_pnp_resume, | 648 | .resume = tpm_tis_pnp_resume, |
| 649 | .remove = tpm_tis_pnp_remove, | ||
| 639 | }; | 650 | }; |
| 640 | 651 | ||
| 641 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 | 652 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 |
| @@ -683,6 +694,7 @@ static void __exit cleanup_tis(void) | |||
| 683 | spin_lock(&tis_lock); | 694 | spin_lock(&tis_lock); |
| 684 | list_for_each_entry_safe(i, j, &tis_chips, list) { | 695 | list_for_each_entry_safe(i, j, &tis_chips, list) { |
| 685 | chip = to_tpm_chip(i); | 696 | chip = to_tpm_chip(i); |
| 697 | tpm_remove_hardware(chip->dev); | ||
| 686 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | 698 | iowrite32(~TPM_GLOBAL_INT_ENABLE & |
| 687 | ioread32(chip->vendor.iobase + | 699 | ioread32(chip->vendor.iobase + |
| 688 | TPM_INT_ENABLE(chip->vendor. | 700 | TPM_INT_ENABLE(chip->vendor. |
| @@ -694,9 +706,9 @@ static void __exit cleanup_tis(void) | |||
| 694 | free_irq(chip->vendor.irq, chip); | 706 | free_irq(chip->vendor.irq, chip); |
| 695 | iounmap(i->iobase); | 707 | iounmap(i->iobase); |
| 696 | list_del(&i->list); | 708 | list_del(&i->list); |
| 697 | tpm_remove_hardware(chip->dev); | ||
| 698 | } | 709 | } |
| 699 | spin_unlock(&tis_lock); | 710 | spin_unlock(&tis_lock); |
| 711 | |||
| 700 | if (force) { | 712 | if (force) { |
| 701 | platform_device_unregister(pdev); | 713 | platform_device_unregister(pdev); |
| 702 | driver_unregister(&tis_drv); | 714 | driver_unregister(&tis_drv); |
