|
@@ -1031,18 +1031,13 @@ void tpm_remove_hardware(struct device *dev)
|
|
|
|
|
|
spin_unlock(&driver_lock);
|
|
|
|
|
|
- dev_set_drvdata(dev, NULL);
|
|
|
misc_deregister(&chip->vendor.miscdev);
|
|
|
- kfree(chip->vendor.miscdev.name);
|
|
|
|
|
|
sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
|
|
|
tpm_bios_log_teardown(chip->bios_dir);
|
|
|
|
|
|
- clear_bit(chip->dev_num, dev_mask);
|
|
|
-
|
|
|
- kfree(chip);
|
|
|
-
|
|
|
- put_device(dev);
|
|
|
+ /* write it this way to be explicit (chip->dev == dev) */
|
|
|
+ put_device(chip->dev);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(tpm_remove_hardware);
|
|
|
|
|
@@ -1082,6 +1077,26 @@ int tpm_pm_resume(struct device *dev)
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(tpm_pm_resume);
|
|
|
|
|
|
+/*
|
|
|
+ * Once all references to platform device are down to 0,
|
|
|
+ * release all allocated structures.
|
|
|
+ * In case vendor provided release function,
|
|
|
+ * call it too.
|
|
|
+ */
|
|
|
+static void tpm_dev_release(struct device *dev)
|
|
|
+{
|
|
|
+ struct tpm_chip *chip = dev_get_drvdata(dev);
|
|
|
+
|
|
|
+ if (chip->vendor.release)
|
|
|
+ chip->vendor.release(dev);
|
|
|
+
|
|
|
+ chip->release(dev);
|
|
|
+
|
|
|
+ clear_bit(chip->dev_num, dev_mask);
|
|
|
+ kfree(chip->vendor.miscdev.name);
|
|
|
+ kfree(chip);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Called from tpm_<specific>.c probe function only for devices
|
|
|
* the driver has determined it should claim. Prior to calling
|
|
@@ -1136,23 +1151,21 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
|
|
|
|
|
|
chip->vendor.miscdev.parent = dev;
|
|
|
chip->dev = get_device(dev);
|
|
|
+ chip->release = dev->release;
|
|
|
+ dev->release = tpm_dev_release;
|
|
|
+ dev_set_drvdata(dev, chip);
|
|
|
|
|
|
if (misc_register(&chip->vendor.miscdev)) {
|
|
|
dev_err(chip->dev,
|
|
|
"unable to misc_register %s, minor %d\n",
|
|
|
chip->vendor.miscdev.name,
|
|
|
chip->vendor.miscdev.minor);
|
|
|
- put_device(dev);
|
|
|
- clear_bit(chip->dev_num, dev_mask);
|
|
|
- kfree(chip);
|
|
|
- kfree(devname);
|
|
|
+ put_device(chip->dev);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
spin_lock(&driver_lock);
|
|
|
|
|
|
- dev_set_drvdata(dev, chip);
|
|
|
-
|
|
|
list_add(&chip->list, &tpm_chip_list);
|
|
|
|
|
|
spin_unlock(&driver_lock);
|
|
@@ -1160,10 +1173,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
|
|
|
if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) {
|
|
|
list_del(&chip->list);
|
|
|
misc_deregister(&chip->vendor.miscdev);
|
|
|
- put_device(dev);
|
|
|
- clear_bit(chip->dev_num, dev_mask);
|
|
|
- kfree(chip);
|
|
|
- kfree(devname);
|
|
|
+ put_device(chip->dev);
|
|
|
return NULL;
|
|
|
}
|
|
|
|