diff options
| -rw-r--r-- | drivers/char/tpm/tpm.c | 44 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm.h | 2 |
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 | } |
| 1047 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); | 1042 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); |
| 1048 | 1043 | ||
| @@ -1083,6 +1078,26 @@ int tpm_pm_resume(struct device *dev) | |||
| 1083 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 1078 | EXPORT_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 | */ | ||
| 1086 | static 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) |
