aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tpm/tpm.c44
-rw-r--r--drivers/char/tpm/tpm.h2
2 files changed, 29 insertions, 17 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index c88424a0c89b..a5d8bcb40000 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -1031,18 +1031,13 @@ void tpm_remove_hardware(struct device *dev)
1031 1031
1032 spin_unlock(&driver_lock); 1032 spin_unlock(&driver_lock);
1033 1033
1034 dev_set_drvdata(dev, NULL);
1035 misc_deregister(&chip->vendor.miscdev); 1034 misc_deregister(&chip->vendor.miscdev);
1036 kfree(chip->vendor.miscdev.name);
1037 1035
1038 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); 1036 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
1039 tpm_bios_log_teardown(chip->bios_dir); 1037 tpm_bios_log_teardown(chip->bios_dir);
1040 1038
1041 clear_bit(chip->dev_num, dev_mask); 1039 /* write it this way to be explicit (chip->dev == dev) */
1042 1040 put_device(chip->dev);
1043 kfree(chip);
1044
1045 put_device(dev);
1046} 1041}
1047EXPORT_SYMBOL_GPL(tpm_remove_hardware); 1042EXPORT_SYMBOL_GPL(tpm_remove_hardware);
1048 1043
@@ -1083,6 +1078,26 @@ int tpm_pm_resume(struct device *dev)
1083EXPORT_SYMBOL_GPL(tpm_pm_resume); 1078EXPORT_SYMBOL_GPL(tpm_pm_resume);
1084 1079
1085/* 1080/*
1081 * Once all references to platform device are down to 0,
1082 * release all allocated structures.
1083 * In case vendor provided release function,
1084 * call it too.
1085 */
1086static void tpm_dev_release(struct device *dev)
1087{
1088 struct tpm_chip *chip = dev_get_drvdata(dev);
1089
1090 if (chip->vendor.release)
1091 chip->vendor.release(dev);
1092
1093 chip->release(dev);
1094
1095 clear_bit(chip->dev_num, dev_mask);
1096 kfree(chip->vendor.miscdev.name);
1097 kfree(chip);
1098}
1099
1100/*
1086 * Called from tpm_<specific>.c probe function only for devices 1101 * Called from tpm_<specific>.c probe function only for devices
1087 * the driver has determined it should claim. Prior to calling 1102 * the driver has determined it should claim. Prior to calling
1088 * this function the specific probe function has called pci_enable_device 1103 * this function the specific probe function has called pci_enable_device
@@ -1136,23 +1151,21 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1136 1151
1137 chip->vendor.miscdev.parent = dev; 1152 chip->vendor.miscdev.parent = dev;
1138 chip->dev = get_device(dev); 1153 chip->dev = get_device(dev);
1154 chip->release = dev->release;
1155 dev->release = tpm_dev_release;
1156 dev_set_drvdata(dev, chip);
1139 1157
1140 if (misc_register(&chip->vendor.miscdev)) { 1158 if (misc_register(&chip->vendor.miscdev)) {
1141 dev_err(chip->dev, 1159 dev_err(chip->dev,
1142 "unable to misc_register %s, minor %d\n", 1160 "unable to misc_register %s, minor %d\n",
1143 chip->vendor.miscdev.name, 1161 chip->vendor.miscdev.name,
1144 chip->vendor.miscdev.minor); 1162 chip->vendor.miscdev.minor);
1145 put_device(dev); 1163 put_device(chip->dev);
1146 clear_bit(chip->dev_num, dev_mask);
1147 kfree(chip);
1148 kfree(devname);
1149 return NULL; 1164 return NULL;
1150 } 1165 }
1151 1166
1152 spin_lock(&driver_lock); 1167 spin_lock(&driver_lock);
1153 1168
1154 dev_set_drvdata(dev, chip);
1155
1156 list_add(&chip->list, &tpm_chip_list); 1169 list_add(&chip->list, &tpm_chip_list);
1157 1170
1158 spin_unlock(&driver_lock); 1171 spin_unlock(&driver_lock);
@@ -1160,10 +1173,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1160 if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { 1173 if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
1161 list_del(&chip->list); 1174 list_del(&chip->list);
1162 misc_deregister(&chip->vendor.miscdev); 1175 misc_deregister(&chip->vendor.miscdev);
1163 put_device(dev); 1176 put_device(chip->dev);
1164 clear_bit(chip->dev_num, dev_mask);
1165 kfree(chip);
1166 kfree(devname);
1167 return NULL; 1177 return NULL;
1168 } 1178 }
1169 1179
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index d15ccddc92eb..e885148b4cfb 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -74,6 +74,7 @@ struct tpm_vendor_specific {
74 int (*send) (struct tpm_chip *, u8 *, size_t); 74 int (*send) (struct tpm_chip *, u8 *, size_t);
75 void (*cancel) (struct tpm_chip *); 75 void (*cancel) (struct tpm_chip *);
76 u8 (*status) (struct tpm_chip *); 76 u8 (*status) (struct tpm_chip *);
77 void (*release) (struct device *);
77 struct miscdevice miscdev; 78 struct miscdevice miscdev;
78 struct attribute_group *attr_group; 79 struct attribute_group *attr_group;
79 struct list_head list; 80 struct list_head list;
@@ -106,6 +107,7 @@ struct tpm_chip {
106 struct dentry **bios_dir; 107 struct dentry **bios_dir;
107 108
108 struct list_head list; 109 struct list_head list;
110 void (*release) (struct device *);
109}; 111};
110 112
111#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) 113#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)