aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm
diff options
context:
space:
mode:
authorRajiv Andrade <srajiv@linux.vnet.ibm.com>2008-10-10 18:04:39 -0400
committerJames Morris <jmorris@namei.org>2008-10-10 18:04:39 -0400
commit253115b71fa06330bd58afbe01ccaf763a8a0cf1 (patch)
tree5b2ce62ca88fa461f7d3466361b8c4599ea82ea0 /drivers/char/tpm
parentf02a93645e6200a9da0f26dac8ced28c612f5e86 (diff)
The tpm_dev_release function is only called for platform devices, not pnp
devices, so we implemented the .remove function for pnp ones. Since it's code is very similar to the one inside tpm_dev_release, we've created a helper function tpm_dev_vendor_release, which is called by both. Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> Signed-off-by: Rajiv Andrade <srajiv@linux.vnet.ibm.com> Cc: "Serge E. Hallyn" <serue@us.ibm.com> Cc: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r--drivers/char/tpm/tpm.c22
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/char/tpm/tpm_tis.c14
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}
1134EXPORT_SYMBOL_GPL(tpm_pm_resume); 1134EXPORT_SYMBOL_GPL(tpm_pm_resume);
1135 1135
1136/* In case vendor provided release function, call it too.*/
1137
1138void 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}
1146EXPORT_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 */
1141static void tpm_dev_release(struct device *dev) 1153static 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}
1162EXPORT_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 *);
133extern int tpm_open(struct inode *, struct file *); 133extern int tpm_open(struct inode *, struct file *);
134extern int tpm_release(struct inode *, struct file *); 134extern int tpm_release(struct inode *, struct file *);
135extern void tpm_dev_vendor_release(struct tpm_chip *);
135extern ssize_t tpm_write(struct file *, const char __user *, size_t, 136extern ssize_t tpm_write(struct file *, const char __user *, size_t,
136 loff_t *); 137 loff_t *);
137extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); 138extern 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
633static __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
633static struct pnp_driver tis_pnp_driver = { 643static 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);