aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tpm/tpm.c25
1 files changed, 7 insertions, 18 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 160dc080d580..6889e7db3aff 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -32,7 +32,6 @@ enum tpm_const {
32 TPM_MINOR = 224, /* officially assigned */ 32 TPM_MINOR = 224, /* officially assigned */
33 TPM_BUFSIZE = 2048, 33 TPM_BUFSIZE = 2048,
34 TPM_NUM_DEVICES = 256, 34 TPM_NUM_DEVICES = 256,
35 TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
36}; 35};
37 36
38enum tpm_duration { 37enum tpm_duration {
@@ -48,7 +47,7 @@ enum tpm_duration {
48 47
49static LIST_HEAD(tpm_chip_list); 48static LIST_HEAD(tpm_chip_list);
50static DEFINE_SPINLOCK(driver_lock); 49static DEFINE_SPINLOCK(driver_lock);
51static int dev_mask[TPM_NUM_MASK_ENTRIES]; 50static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
52 51
53/* 52/*
54 * Array with one entry per ordinal defining the maximum amount 53 * Array with one entry per ordinal defining the maximum amount
@@ -1038,8 +1037,7 @@ void tpm_remove_hardware(struct device *dev)
1038 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); 1037 sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
1039 tpm_bios_log_teardown(chip->bios_dir); 1038 tpm_bios_log_teardown(chip->bios_dir);
1040 1039
1041 dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES] &= 1040 clear_bit(chip->dev_num, dev_mask);
1042 ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
1043 1041
1044 kfree(chip); 1042 kfree(chip);
1045 1043
@@ -1097,7 +1095,6 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1097 1095
1098 char *devname; 1096 char *devname;
1099 struct tpm_chip *chip; 1097 struct tpm_chip *chip;
1100 int i, j;
1101 1098
1102 /* Driver specific per-device data */ 1099 /* Driver specific per-device data */
1103 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1100 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1116,19 +1113,9 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1116 1113
1117 memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific)); 1114 memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
1118 1115
1119 chip->dev_num = -1; 1116 chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
1120 1117
1121 for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++) 1118 if (chip->dev_num >= TPM_NUM_DEVICES) {
1122 for (j = 0; j < 8 * sizeof(int); j++)
1123 if ((dev_mask[i] & (1 << j)) == 0) {
1124 chip->dev_num =
1125 i * TPM_NUM_MASK_ENTRIES + j;
1126 dev_mask[i] |= 1 << j;
1127 goto dev_num_search_complete;
1128 }
1129
1130dev_num_search_complete:
1131 if (chip->dev_num < 0) {
1132 dev_err(dev, "No available tpm device numbers\n"); 1119 dev_err(dev, "No available tpm device numbers\n");
1133 kfree(chip); 1120 kfree(chip);
1134 return NULL; 1121 return NULL;
@@ -1137,6 +1124,8 @@ dev_num_search_complete:
1137 else 1124 else
1138 chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; 1125 chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
1139 1126
1127 set_bit(chip->dev_num, dev_mask);
1128
1140 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); 1129 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
1141 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); 1130 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
1142 chip->vendor.miscdev.name = devname; 1131 chip->vendor.miscdev.name = devname;
@@ -1150,8 +1139,8 @@ dev_num_search_complete:
1150 chip->vendor.miscdev.name, 1139 chip->vendor.miscdev.name,
1151 chip->vendor.miscdev.minor); 1140 chip->vendor.miscdev.minor);
1152 put_device(dev); 1141 put_device(dev);
1142 clear_bit(chip->dev_num, dev_mask);
1153 kfree(chip); 1143 kfree(chip);
1154 dev_mask[i] &= !(1 << j);
1155 return NULL; 1144 return NULL;
1156 } 1145 }
1157 1146