diff options
Diffstat (limited to 'drivers')
-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); |