diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tpm/Makefile | 2 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-chip.c | 199 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 148 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 16 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_atmel.c | 11 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_atmel.c | 39 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_infineon.c | 37 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_nuvoton.c | 47 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_i2c_stm_st33.c | 14 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_ibmvtpm.c | 17 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_infineon.c | 29 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_nsc.c | 14 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_tis.c | 80 | ||||
-rw-r--r-- | drivers/char/tpm/xen-tpmfront.c | 14 |
14 files changed, 329 insertions, 338 deletions
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index 7f54dae847e4..c715596acb7c 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the kernel tpm device drivers. | 2 | # Makefile for the kernel tpm device drivers. |
3 | # | 3 | # |
4 | obj-$(CONFIG_TCG_TPM) += tpm.o | 4 | obj-$(CONFIG_TCG_TPM) += tpm.o |
5 | tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o | 5 | tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o |
6 | tpm-$(CONFIG_ACPI) += tpm_ppi.o | 6 | tpm-$(CONFIG_ACPI) += tpm_ppi.o |
7 | 7 | ||
8 | ifdef CONFIG_ACPI | 8 | ifdef CONFIG_ACPI |
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c new file mode 100644 index 000000000000..7dc9999e2d54 --- /dev/null +++ b/drivers/char/tpm/tpm-chip.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 IBM Corporation | ||
3 | * Copyright (C) 2014 Intel Corporation | ||
4 | * | ||
5 | * Authors: | ||
6 | * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | ||
7 | * Leendert van Doorn <leendert@watson.ibm.com> | ||
8 | * Dave Safford <safford@watson.ibm.com> | ||
9 | * Reiner Sailer <sailer@watson.ibm.com> | ||
10 | * Kylene Hall <kjhall@us.ibm.com> | ||
11 | * | ||
12 | * Maintained by: <tpmdd-devel@lists.sourceforge.net> | ||
13 | * | ||
14 | * TPM chip management routines. | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License as | ||
18 | * published by the Free Software Foundation, version 2 of the | ||
19 | * License. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/poll.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/spinlock.h> | ||
27 | #include <linux/freezer.h> | ||
28 | #include "tpm.h" | ||
29 | #include "tpm_eventlog.h" | ||
30 | |||
31 | static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); | ||
32 | static LIST_HEAD(tpm_chip_list); | ||
33 | static DEFINE_SPINLOCK(driver_lock); | ||
34 | |||
35 | /* | ||
36 | * tpm_chip_find_get - return tpm_chip for a given chip number | ||
37 | * @chip_num the device number for the chip | ||
38 | */ | ||
39 | struct tpm_chip *tpm_chip_find_get(int chip_num) | ||
40 | { | ||
41 | struct tpm_chip *pos, *chip = NULL; | ||
42 | |||
43 | rcu_read_lock(); | ||
44 | list_for_each_entry_rcu(pos, &tpm_chip_list, list) { | ||
45 | if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num) | ||
46 | continue; | ||
47 | |||
48 | if (try_module_get(pos->dev->driver->owner)) { | ||
49 | chip = pos; | ||
50 | break; | ||
51 | } | ||
52 | } | ||
53 | rcu_read_unlock(); | ||
54 | return chip; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * tpmm_chip_remove() - free chip memory and device number | ||
59 | * @data: points to struct tpm_chip instance | ||
60 | * | ||
61 | * This is used internally by tpmm_chip_alloc() and called by devres | ||
62 | * when the device is released. This function does the opposite of | ||
63 | * tpmm_chip_alloc() freeing memory and the device number. | ||
64 | */ | ||
65 | static void tpmm_chip_remove(void *data) | ||
66 | { | ||
67 | struct tpm_chip *chip = (struct tpm_chip *) data; | ||
68 | |||
69 | spin_lock(&driver_lock); | ||
70 | clear_bit(chip->dev_num, dev_mask); | ||
71 | spin_unlock(&driver_lock); | ||
72 | kfree(chip); | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * tpmm_chip_alloc() - allocate a new struct tpm_chip instance | ||
77 | * @dev: device to which the chip is associated | ||
78 | * @ops: struct tpm_class_ops instance | ||
79 | * | ||
80 | * Allocates a new struct tpm_chip instance and assigns a free | ||
81 | * device number for it. Caller does not have to worry about | ||
82 | * freeing the allocated resources. When the devices is removed | ||
83 | * devres calls tpmm_chip_remove() to do the job. | ||
84 | */ | ||
85 | struct tpm_chip *tpmm_chip_alloc(struct device *dev, | ||
86 | const struct tpm_class_ops *ops) | ||
87 | { | ||
88 | struct tpm_chip *chip; | ||
89 | |||
90 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
91 | if (chip == NULL) | ||
92 | return ERR_PTR(-ENOMEM); | ||
93 | |||
94 | mutex_init(&chip->tpm_mutex); | ||
95 | INIT_LIST_HEAD(&chip->list); | ||
96 | |||
97 | chip->ops = ops; | ||
98 | |||
99 | spin_lock(&driver_lock); | ||
100 | chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); | ||
101 | spin_unlock(&driver_lock); | ||
102 | |||
103 | if (chip->dev_num >= TPM_NUM_DEVICES) { | ||
104 | dev_err(dev, "No available tpm device numbers\n"); | ||
105 | kfree(chip); | ||
106 | return ERR_PTR(-ENOMEM); | ||
107 | } | ||
108 | |||
109 | set_bit(chip->dev_num, dev_mask); | ||
110 | |||
111 | scnprintf(chip->devname, sizeof(chip->devname), "tpm%d", chip->dev_num); | ||
112 | |||
113 | chip->dev = dev; | ||
114 | devm_add_action(dev, tpmm_chip_remove, chip); | ||
115 | dev_set_drvdata(dev, chip); | ||
116 | |||
117 | return chip; | ||
118 | } | ||
119 | EXPORT_SYMBOL_GPL(tpmm_chip_alloc); | ||
120 | |||
121 | /* | ||
122 | * tpm_chip_register() - create a misc driver for the TPM chip | ||
123 | * @chip: TPM chip to use. | ||
124 | * | ||
125 | * Creates a misc driver for the TPM chip and adds sysfs interfaces for | ||
126 | * the device, PPI and TCPA. As the last step this function adds the | ||
127 | * chip to the list of TPM chips available for use. | ||
128 | * | ||
129 | * NOTE: This function should be only called after the chip initialization | ||
130 | * is complete. | ||
131 | * | ||
132 | * Called from tpm_<specific>.c probe function only for devices | ||
133 | * the driver has determined it should claim. Prior to calling | ||
134 | * this function the specific probe function has called pci_enable_device | ||
135 | * upon errant exit from this function specific probe function should call | ||
136 | * pci_disable_device | ||
137 | */ | ||
138 | int tpm_chip_register(struct tpm_chip *chip) | ||
139 | { | ||
140 | int rc; | ||
141 | |||
142 | rc = tpm_dev_add_device(chip); | ||
143 | if (rc) | ||
144 | return rc; | ||
145 | |||
146 | rc = tpm_sysfs_add_device(chip); | ||
147 | if (rc) | ||
148 | goto del_misc; | ||
149 | |||
150 | rc = tpm_add_ppi(&chip->dev->kobj); | ||
151 | if (rc) | ||
152 | goto del_sysfs; | ||
153 | |||
154 | chip->bios_dir = tpm_bios_log_setup(chip->devname); | ||
155 | |||
156 | /* Make the chip available. */ | ||
157 | spin_lock(&driver_lock); | ||
158 | list_add_rcu(&chip->list, &tpm_chip_list); | ||
159 | spin_unlock(&driver_lock); | ||
160 | |||
161 | chip->flags |= TPM_CHIP_FLAG_REGISTERED; | ||
162 | |||
163 | return 0; | ||
164 | del_sysfs: | ||
165 | tpm_sysfs_del_device(chip); | ||
166 | del_misc: | ||
167 | tpm_dev_del_device(chip); | ||
168 | return rc; | ||
169 | } | ||
170 | EXPORT_SYMBOL_GPL(tpm_chip_register); | ||
171 | |||
172 | /* | ||
173 | * tpm_chip_unregister() - release the TPM driver | ||
174 | * @chip: TPM chip to use. | ||
175 | * | ||
176 | * Takes the chip first away from the list of available TPM chips and then | ||
177 | * cleans up all the resources reserved by tpm_chip_register(). | ||
178 | * | ||
179 | * NOTE: This function should be only called before deinitializing chip | ||
180 | * resources. | ||
181 | */ | ||
182 | void tpm_chip_unregister(struct tpm_chip *chip) | ||
183 | { | ||
184 | if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED)) | ||
185 | return; | ||
186 | |||
187 | spin_lock(&driver_lock); | ||
188 | list_del_rcu(&chip->list); | ||
189 | spin_unlock(&driver_lock); | ||
190 | synchronize_rcu(); | ||
191 | |||
192 | if (chip->bios_dir) | ||
193 | tpm_bios_log_teardown(chip->bios_dir); | ||
194 | tpm_remove_ppi(&chip->dev->kobj); | ||
195 | tpm_sysfs_del_device(chip); | ||
196 | |||
197 | tpm_dev_del_device(chip); | ||
198 | } | ||
199 | EXPORT_SYMBOL_GPL(tpm_chip_unregister); | ||
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index c17aa45024aa..4dbed1e45abd 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004 IBM Corporation | 2 | * Copyright (C) 2004 IBM Corporation |
3 | * Copyright (C) 2014 Intel Corporation | ||
3 | * | 4 | * |
4 | * Authors: | 5 | * Authors: |
5 | * Leendert van Doorn <leendert@watson.ibm.com> | 6 | * Leendert van Doorn <leendert@watson.ibm.com> |
@@ -47,10 +48,6 @@ module_param_named(suspend_pcr, tpm_suspend_pcr, uint, 0644); | |||
47 | MODULE_PARM_DESC(suspend_pcr, | 48 | MODULE_PARM_DESC(suspend_pcr, |
48 | "PCR to use for dummy writes to faciltate flush on suspend."); | 49 | "PCR to use for dummy writes to faciltate flush on suspend."); |
49 | 50 | ||
50 | static LIST_HEAD(tpm_chip_list); | ||
51 | static DEFINE_SPINLOCK(driver_lock); | ||
52 | static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); | ||
53 | |||
54 | /* | 51 | /* |
55 | * Array with one entry per ordinal defining the maximum amount | 52 | * Array with one entry per ordinal defining the maximum amount |
56 | * of time the chip could take to return the result. The ordinal | 53 | * of time the chip could take to return the result. The ordinal |
@@ -639,27 +636,6 @@ static int tpm_continue_selftest(struct tpm_chip *chip) | |||
639 | return rc; | 636 | return rc; |
640 | } | 637 | } |
641 | 638 | ||
642 | /* | ||
643 | * tpm_chip_find_get - return tpm_chip for given chip number | ||
644 | */ | ||
645 | static struct tpm_chip *tpm_chip_find_get(int chip_num) | ||
646 | { | ||
647 | struct tpm_chip *pos, *chip = NULL; | ||
648 | |||
649 | rcu_read_lock(); | ||
650 | list_for_each_entry_rcu(pos, &tpm_chip_list, list) { | ||
651 | if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num) | ||
652 | continue; | ||
653 | |||
654 | if (try_module_get(pos->dev->driver->owner)) { | ||
655 | chip = pos; | ||
656 | break; | ||
657 | } | ||
658 | } | ||
659 | rcu_read_unlock(); | ||
660 | return chip; | ||
661 | } | ||
662 | |||
663 | #define TPM_ORDINAL_PCRREAD cpu_to_be32(21) | 639 | #define TPM_ORDINAL_PCRREAD cpu_to_be32(21) |
664 | #define READ_PCR_RESULT_SIZE 30 | 640 | #define READ_PCR_RESULT_SIZE 30 |
665 | static struct tpm_input_header pcrread_header = { | 641 | static struct tpm_input_header pcrread_header = { |
@@ -887,30 +863,6 @@ again: | |||
887 | } | 863 | } |
888 | EXPORT_SYMBOL_GPL(wait_for_tpm_stat); | 864 | EXPORT_SYMBOL_GPL(wait_for_tpm_stat); |
889 | 865 | ||
890 | void tpm_remove_hardware(struct device *dev) | ||
891 | { | ||
892 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
893 | |||
894 | if (chip == NULL) { | ||
895 | dev_err(dev, "No device data found\n"); | ||
896 | return; | ||
897 | } | ||
898 | |||
899 | spin_lock(&driver_lock); | ||
900 | list_del_rcu(&chip->list); | ||
901 | spin_unlock(&driver_lock); | ||
902 | synchronize_rcu(); | ||
903 | |||
904 | tpm_dev_del_device(chip); | ||
905 | tpm_sysfs_del_device(chip); | ||
906 | tpm_remove_ppi(&dev->kobj); | ||
907 | tpm_bios_log_teardown(chip->bios_dir); | ||
908 | |||
909 | /* write it this way to be explicit (chip->dev == dev) */ | ||
910 | put_device(chip->dev); | ||
911 | } | ||
912 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); | ||
913 | |||
914 | #define TPM_ORD_SAVESTATE cpu_to_be32(152) | 866 | #define TPM_ORD_SAVESTATE cpu_to_be32(152) |
915 | #define SAVESTATE_RESULT_SIZE 10 | 867 | #define SAVESTATE_RESULT_SIZE 10 |
916 | 868 | ||
@@ -1044,104 +996,6 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) | |||
1044 | } | 996 | } |
1045 | EXPORT_SYMBOL_GPL(tpm_get_random); | 997 | EXPORT_SYMBOL_GPL(tpm_get_random); |
1046 | 998 | ||
1047 | /* In case vendor provided release function, call it too.*/ | ||
1048 | |||
1049 | void tpm_dev_vendor_release(struct tpm_chip *chip) | ||
1050 | { | ||
1051 | if (!chip) | ||
1052 | return; | ||
1053 | |||
1054 | clear_bit(chip->dev_num, dev_mask); | ||
1055 | } | ||
1056 | EXPORT_SYMBOL_GPL(tpm_dev_vendor_release); | ||
1057 | |||
1058 | |||
1059 | /* | ||
1060 | * Once all references to platform device are down to 0, | ||
1061 | * release all allocated structures. | ||
1062 | */ | ||
1063 | static void tpm_dev_release(struct device *dev) | ||
1064 | { | ||
1065 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
1066 | |||
1067 | if (!chip) | ||
1068 | return; | ||
1069 | |||
1070 | tpm_dev_vendor_release(chip); | ||
1071 | |||
1072 | chip->release(dev); | ||
1073 | kfree(chip); | ||
1074 | } | ||
1075 | |||
1076 | /* | ||
1077 | * Called from tpm_<specific>.c probe function only for devices | ||
1078 | * the driver has determined it should claim. Prior to calling | ||
1079 | * this function the specific probe function has called pci_enable_device | ||
1080 | * upon errant exit from this function specific probe function should call | ||
1081 | * pci_disable_device | ||
1082 | */ | ||
1083 | struct tpm_chip *tpm_register_hardware(struct device *dev, | ||
1084 | const struct tpm_class_ops *ops) | ||
1085 | { | ||
1086 | struct tpm_chip *chip; | ||
1087 | |||
1088 | /* Driver specific per-device data */ | ||
1089 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
1090 | |||
1091 | if (chip == NULL) | ||
1092 | return NULL; | ||
1093 | |||
1094 | mutex_init(&chip->tpm_mutex); | ||
1095 | INIT_LIST_HEAD(&chip->list); | ||
1096 | |||
1097 | chip->ops = ops; | ||
1098 | chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); | ||
1099 | |||
1100 | if (chip->dev_num >= TPM_NUM_DEVICES) { | ||
1101 | dev_err(dev, "No available tpm device numbers\n"); | ||
1102 | goto out_free; | ||
1103 | } | ||
1104 | |||
1105 | set_bit(chip->dev_num, dev_mask); | ||
1106 | |||
1107 | scnprintf(chip->devname, sizeof(chip->devname), "%s%d", "tpm", | ||
1108 | chip->dev_num); | ||
1109 | |||
1110 | chip->dev = get_device(dev); | ||
1111 | chip->release = dev->release; | ||
1112 | dev->release = tpm_dev_release; | ||
1113 | dev_set_drvdata(dev, chip); | ||
1114 | |||
1115 | if (tpm_dev_add_device(chip)) | ||
1116 | goto put_device; | ||
1117 | |||
1118 | if (tpm_sysfs_add_device(chip)) | ||
1119 | goto del_misc; | ||
1120 | |||
1121 | if (tpm_add_ppi(&dev->kobj)) | ||
1122 | goto del_sysfs; | ||
1123 | |||
1124 | chip->bios_dir = tpm_bios_log_setup(chip->devname); | ||
1125 | |||
1126 | /* Make chip available */ | ||
1127 | spin_lock(&driver_lock); | ||
1128 | list_add_tail_rcu(&chip->list, &tpm_chip_list); | ||
1129 | spin_unlock(&driver_lock); | ||
1130 | |||
1131 | return chip; | ||
1132 | |||
1133 | del_sysfs: | ||
1134 | tpm_sysfs_del_device(chip); | ||
1135 | del_misc: | ||
1136 | tpm_dev_del_device(chip); | ||
1137 | put_device: | ||
1138 | put_device(chip->dev); | ||
1139 | out_free: | ||
1140 | kfree(chip); | ||
1141 | return NULL; | ||
1142 | } | ||
1143 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | ||
1144 | |||
1145 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); | 999 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); |
1146 | MODULE_DESCRIPTION("TPM Driver"); | 1000 | MODULE_DESCRIPTION("TPM Driver"); |
1147 | MODULE_VERSION("2.0"); | 1001 | MODULE_VERSION("2.0"); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index e638eb016b90..72ff18c872d3 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -94,9 +94,14 @@ struct tpm_vendor_specific { | |||
94 | #define TPM_VID_WINBOND 0x1050 | 94 | #define TPM_VID_WINBOND 0x1050 |
95 | #define TPM_VID_STM 0x104A | 95 | #define TPM_VID_STM 0x104A |
96 | 96 | ||
97 | enum tpm_chip_flags { | ||
98 | TPM_CHIP_FLAG_REGISTERED = BIT(0), | ||
99 | }; | ||
100 | |||
97 | struct tpm_chip { | 101 | struct tpm_chip { |
98 | struct device *dev; /* Device stuff */ | 102 | struct device *dev; /* Device stuff */ |
99 | const struct tpm_class_ops *ops; | 103 | const struct tpm_class_ops *ops; |
104 | unsigned int flags; | ||
100 | 105 | ||
101 | int dev_num; /* /dev/tpm# */ | 106 | int dev_num; /* /dev/tpm# */ |
102 | char devname[7]; | 107 | char devname[7]; |
@@ -110,7 +115,6 @@ struct tpm_chip { | |||
110 | struct dentry **bios_dir; | 115 | struct dentry **bios_dir; |
111 | 116 | ||
112 | struct list_head list; | 117 | struct list_head list; |
113 | void (*release) (struct device *); | ||
114 | }; | 118 | }; |
115 | 119 | ||
116 | #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) | 120 | #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) |
@@ -322,15 +326,17 @@ extern int tpm_get_timeouts(struct tpm_chip *); | |||
322 | extern void tpm_gen_interrupt(struct tpm_chip *); | 326 | extern void tpm_gen_interrupt(struct tpm_chip *); |
323 | extern int tpm_do_selftest(struct tpm_chip *); | 327 | extern int tpm_do_selftest(struct tpm_chip *); |
324 | extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); | 328 | extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); |
325 | extern struct tpm_chip* tpm_register_hardware(struct device *, | ||
326 | const struct tpm_class_ops *ops); | ||
327 | extern void tpm_dev_vendor_release(struct tpm_chip *); | ||
328 | extern void tpm_remove_hardware(struct device *); | ||
329 | extern int tpm_pm_suspend(struct device *); | 329 | extern int tpm_pm_suspend(struct device *); |
330 | extern int tpm_pm_resume(struct device *); | 330 | extern int tpm_pm_resume(struct device *); |
331 | extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, | 331 | extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, |
332 | wait_queue_head_t *, bool); | 332 | wait_queue_head_t *, bool); |
333 | 333 | ||
334 | struct tpm_chip *tpm_chip_find_get(int chip_num); | ||
335 | extern struct tpm_chip *tpmm_chip_alloc(struct device *dev, | ||
336 | const struct tpm_class_ops *ops); | ||
337 | extern int tpm_chip_register(struct tpm_chip *chip); | ||
338 | extern void tpm_chip_unregister(struct tpm_chip *chip); | ||
339 | |||
334 | int tpm_dev_add_device(struct tpm_chip *chip); | 340 | int tpm_dev_add_device(struct tpm_chip *chip); |
335 | void tpm_dev_del_device(struct tpm_chip *chip); | 341 | void tpm_dev_del_device(struct tpm_chip *chip); |
336 | int tpm_sysfs_add_device(struct tpm_chip *chip); | 342 | int tpm_sysfs_add_device(struct tpm_chip *chip); |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 435c8b9dd2f8..3d4c6c3b0433 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -138,11 +138,11 @@ static void atml_plat_remove(void) | |||
138 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); | 138 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); |
139 | 139 | ||
140 | if (chip) { | 140 | if (chip) { |
141 | tpm_chip_unregister(chip); | ||
141 | if (chip->vendor.have_region) | 142 | if (chip->vendor.have_region) |
142 | atmel_release_region(chip->vendor.base, | 143 | atmel_release_region(chip->vendor.base, |
143 | chip->vendor.region_size); | 144 | chip->vendor.region_size); |
144 | atmel_put_base_addr(chip->vendor.iobase); | 145 | atmel_put_base_addr(chip->vendor.iobase); |
145 | tpm_remove_hardware(chip->dev); | ||
146 | platform_device_unregister(pdev); | 146 | platform_device_unregister(pdev); |
147 | } | 147 | } |
148 | } | 148 | } |
@@ -183,8 +183,9 @@ static int __init init_atmel(void) | |||
183 | goto err_rel_reg; | 183 | goto err_rel_reg; |
184 | } | 184 | } |
185 | 185 | ||
186 | if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) { | 186 | chip = tpmm_chip_alloc(&pdev->dev, &tpm_atmel); |
187 | rc = -ENODEV; | 187 | if (IS_ERR(chip)) { |
188 | rc = PTR_ERR(chip); | ||
188 | goto err_unreg_dev; | 189 | goto err_unreg_dev; |
189 | } | 190 | } |
190 | 191 | ||
@@ -193,6 +194,10 @@ static int __init init_atmel(void) | |||
193 | chip->vendor.have_region = have_region; | 194 | chip->vendor.have_region = have_region; |
194 | chip->vendor.region_size = region_size; | 195 | chip->vendor.region_size = region_size; |
195 | 196 | ||
197 | rc = tpm_chip_register(chip); | ||
198 | if (rc) | ||
199 | goto err_unreg_dev; | ||
200 | |||
196 | return 0; | 201 | return 0; |
197 | 202 | ||
198 | err_unreg_dev: | 203 | err_unreg_dev: |
diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 5f448886417f..643a9402e911 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c | |||
@@ -153,25 +153,20 @@ static const struct tpm_class_ops i2c_atmel = { | |||
153 | static int i2c_atmel_probe(struct i2c_client *client, | 153 | static int i2c_atmel_probe(struct i2c_client *client, |
154 | const struct i2c_device_id *id) | 154 | const struct i2c_device_id *id) |
155 | { | 155 | { |
156 | int rc; | ||
157 | struct tpm_chip *chip; | 156 | struct tpm_chip *chip; |
158 | struct device *dev = &client->dev; | 157 | struct device *dev = &client->dev; |
159 | 158 | ||
160 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) | 159 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
161 | return -ENODEV; | 160 | return -ENODEV; |
162 | 161 | ||
163 | chip = tpm_register_hardware(dev, &i2c_atmel); | 162 | chip = tpmm_chip_alloc(dev, &i2c_atmel); |
164 | if (!chip) { | 163 | if (IS_ERR(chip)) |
165 | dev_err(dev, "%s() error in tpm_register_hardware\n", __func__); | 164 | return PTR_ERR(chip); |
166 | return -ENODEV; | ||
167 | } | ||
168 | 165 | ||
169 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), | 166 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), |
170 | GFP_KERNEL); | 167 | GFP_KERNEL); |
171 | if (!chip->vendor.priv) { | 168 | if (!chip->vendor.priv) |
172 | rc = -ENOMEM; | 169 | return -ENOMEM; |
173 | goto out_err; | ||
174 | } | ||
175 | 170 | ||
176 | /* Default timeouts */ | 171 | /* Default timeouts */ |
177 | chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); | 172 | chip->vendor.timeout_a = msecs_to_jiffies(TPM_I2C_SHORT_TIMEOUT); |
@@ -183,32 +178,20 @@ static int i2c_atmel_probe(struct i2c_client *client, | |||
183 | /* There is no known way to probe for this device, and all version | 178 | /* There is no known way to probe for this device, and all version |
184 | * information seems to be read via TPM commands. Thus we rely on the | 179 | * information seems to be read via TPM commands. Thus we rely on the |
185 | * TPM startup process in the common code to detect the device. */ | 180 | * TPM startup process in the common code to detect the device. */ |
186 | if (tpm_get_timeouts(chip)) { | 181 | if (tpm_get_timeouts(chip)) |
187 | rc = -ENODEV; | 182 | return -ENODEV; |
188 | goto out_err; | ||
189 | } | ||
190 | |||
191 | if (tpm_do_selftest(chip)) { | ||
192 | rc = -ENODEV; | ||
193 | goto out_err; | ||
194 | } | ||
195 | 183 | ||
196 | return 0; | 184 | if (tpm_do_selftest(chip)) |
185 | return -ENODEV; | ||
197 | 186 | ||
198 | out_err: | 187 | return tpm_chip_register(chip); |
199 | tpm_dev_vendor_release(chip); | ||
200 | tpm_remove_hardware(chip->dev); | ||
201 | return rc; | ||
202 | } | 188 | } |
203 | 189 | ||
204 | static int i2c_atmel_remove(struct i2c_client *client) | 190 | static int i2c_atmel_remove(struct i2c_client *client) |
205 | { | 191 | { |
206 | struct device *dev = &(client->dev); | 192 | struct device *dev = &(client->dev); |
207 | struct tpm_chip *chip = dev_get_drvdata(dev); | 193 | struct tpm_chip *chip = dev_get_drvdata(dev); |
208 | 194 | tpm_chip_unregister(chip); | |
209 | tpm_dev_vendor_release(chip); | ||
210 | tpm_remove_hardware(dev); | ||
211 | kfree(chip); | ||
212 | return 0; | 195 | return 0; |
213 | } | 196 | } |
214 | 197 | ||
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 472af4bb1b61..03708e6b309a 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c | |||
@@ -581,12 +581,9 @@ static int tpm_tis_i2c_init(struct device *dev) | |||
581 | int rc = 0; | 581 | int rc = 0; |
582 | struct tpm_chip *chip; | 582 | struct tpm_chip *chip; |
583 | 583 | ||
584 | chip = tpm_register_hardware(dev, &tpm_tis_i2c); | 584 | chip = tpmm_chip_alloc(dev, &tpm_tis_i2c); |
585 | if (!chip) { | 585 | if (IS_ERR(chip)) |
586 | dev_err(dev, "could not register hardware\n"); | 586 | return PTR_ERR(chip); |
587 | rc = -ENODEV; | ||
588 | goto out_err; | ||
589 | } | ||
590 | 587 | ||
591 | /* Disable interrupts */ | 588 | /* Disable interrupts */ |
592 | chip->vendor.irq = 0; | 589 | chip->vendor.irq = 0; |
@@ -600,7 +597,7 @@ static int tpm_tis_i2c_init(struct device *dev) | |||
600 | if (request_locality(chip, 0) != 0) { | 597 | if (request_locality(chip, 0) != 0) { |
601 | dev_err(dev, "could not request locality\n"); | 598 | dev_err(dev, "could not request locality\n"); |
602 | rc = -ENODEV; | 599 | rc = -ENODEV; |
603 | goto out_vendor; | 600 | goto out_err; |
604 | } | 601 | } |
605 | 602 | ||
606 | /* read four bytes from DID_VID register */ | 603 | /* read four bytes from DID_VID register */ |
@@ -628,21 +625,9 @@ static int tpm_tis_i2c_init(struct device *dev) | |||
628 | tpm_get_timeouts(chip); | 625 | tpm_get_timeouts(chip); |
629 | tpm_do_selftest(chip); | 626 | tpm_do_selftest(chip); |
630 | 627 | ||
631 | return 0; | 628 | return tpm_chip_register(chip); |
632 | |||
633 | out_release: | 629 | out_release: |
634 | release_locality(chip, chip->vendor.locality, 1); | 630 | release_locality(chip, chip->vendor.locality, 1); |
635 | |||
636 | out_vendor: | ||
637 | /* close file handles */ | ||
638 | tpm_dev_vendor_release(chip); | ||
639 | |||
640 | /* remove hardware */ | ||
641 | tpm_remove_hardware(chip->dev); | ||
642 | |||
643 | /* reset these pointers, otherwise we oops */ | ||
644 | chip->dev->release = NULL; | ||
645 | chip->release = NULL; | ||
646 | tpm_dev.client = NULL; | 631 | tpm_dev.client = NULL; |
647 | out_err: | 632 | out_err: |
648 | return rc; | 633 | return rc; |
@@ -712,17 +697,9 @@ static int tpm_tis_i2c_probe(struct i2c_client *client, | |||
712 | static int tpm_tis_i2c_remove(struct i2c_client *client) | 697 | static int tpm_tis_i2c_remove(struct i2c_client *client) |
713 | { | 698 | { |
714 | struct tpm_chip *chip = tpm_dev.chip; | 699 | struct tpm_chip *chip = tpm_dev.chip; |
715 | release_locality(chip, chip->vendor.locality, 1); | ||
716 | 700 | ||
717 | /* close file handles */ | 701 | tpm_chip_unregister(chip); |
718 | tpm_dev_vendor_release(chip); | 702 | release_locality(chip, chip->vendor.locality, 1); |
719 | |||
720 | /* remove hardware */ | ||
721 | tpm_remove_hardware(chip->dev); | ||
722 | |||
723 | /* reset these pointers, otherwise we oops */ | ||
724 | chip->dev->release = NULL; | ||
725 | chip->release = NULL; | ||
726 | tpm_dev.client = NULL; | 703 | tpm_dev.client = NULL; |
727 | 704 | ||
728 | return 0; | 705 | return 0; |
diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index bbb4997438c3..8c23088d99ef 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c | |||
@@ -530,18 +530,14 @@ static int i2c_nuvoton_probe(struct i2c_client *client, | |||
530 | dev_info(dev, "VID: %04X DID: %02X RID: %02X\n", (u16) vid, | 530 | dev_info(dev, "VID: %04X DID: %02X RID: %02X\n", (u16) vid, |
531 | (u8) (vid >> 16), (u8) (vid >> 24)); | 531 | (u8) (vid >> 16), (u8) (vid >> 24)); |
532 | 532 | ||
533 | chip = tpm_register_hardware(dev, &tpm_i2c); | 533 | chip = tpmm_chip_alloc(dev, &tpm_i2c); |
534 | if (!chip) { | 534 | if (IS_ERR(chip)) |
535 | dev_err(dev, "%s() error in tpm_register_hardware\n", __func__); | 535 | return PTR_ERR(chip); |
536 | return -ENODEV; | ||
537 | } | ||
538 | 536 | ||
539 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), | 537 | chip->vendor.priv = devm_kzalloc(dev, sizeof(struct priv_data), |
540 | GFP_KERNEL); | 538 | GFP_KERNEL); |
541 | if (!chip->vendor.priv) { | 539 | if (!chip->vendor.priv) |
542 | rc = -ENOMEM; | 540 | return -ENOMEM; |
543 | goto out_err; | ||
544 | } | ||
545 | 541 | ||
546 | init_waitqueue_head(&chip->vendor.read_queue); | 542 | init_waitqueue_head(&chip->vendor.read_queue); |
547 | init_waitqueue_head(&chip->vendor.int_queue); | 543 | init_waitqueue_head(&chip->vendor.int_queue); |
@@ -589,7 +585,7 @@ static int i2c_nuvoton_probe(struct i2c_client *client, | |||
589 | TPM_DATA_FIFO_W, | 585 | TPM_DATA_FIFO_W, |
590 | 1, (u8 *) (&rc)); | 586 | 1, (u8 *) (&rc)); |
591 | if (rc < 0) | 587 | if (rc < 0) |
592 | goto out_err; | 588 | return rc; |
593 | /* TPM_STS <- 0x40 (commandReady) */ | 589 | /* TPM_STS <- 0x40 (commandReady) */ |
594 | i2c_nuvoton_ready(chip); | 590 | i2c_nuvoton_ready(chip); |
595 | } else { | 591 | } else { |
@@ -599,44 +595,29 @@ static int i2c_nuvoton_probe(struct i2c_client *client, | |||
599 | * only TPM_STS_VALID should be set | 595 | * only TPM_STS_VALID should be set |
600 | */ | 596 | */ |
601 | if (i2c_nuvoton_read_status(chip) != | 597 | if (i2c_nuvoton_read_status(chip) != |
602 | TPM_STS_VALID) { | 598 | TPM_STS_VALID) |
603 | rc = -EIO; | 599 | return -EIO; |
604 | goto out_err; | ||
605 | } | ||
606 | } | 600 | } |
607 | } | 601 | } |
608 | } | 602 | } |
609 | 603 | ||
610 | if (tpm_get_timeouts(chip)) { | 604 | if (tpm_get_timeouts(chip)) |
611 | rc = -ENODEV; | 605 | return -ENODEV; |
612 | goto out_err; | ||
613 | } | ||
614 | |||
615 | if (tpm_do_selftest(chip)) { | ||
616 | rc = -ENODEV; | ||
617 | goto out_err; | ||
618 | } | ||
619 | 606 | ||
620 | return 0; | 607 | if (tpm_do_selftest(chip)) |
608 | return -ENODEV; | ||
621 | 609 | ||
622 | out_err: | 610 | return tpm_chip_register(chip); |
623 | tpm_dev_vendor_release(chip); | ||
624 | tpm_remove_hardware(chip->dev); | ||
625 | return rc; | ||
626 | } | 611 | } |
627 | 612 | ||
628 | static int i2c_nuvoton_remove(struct i2c_client *client) | 613 | static int i2c_nuvoton_remove(struct i2c_client *client) |
629 | { | 614 | { |
630 | struct device *dev = &(client->dev); | 615 | struct device *dev = &(client->dev); |
631 | struct tpm_chip *chip = dev_get_drvdata(dev); | 616 | struct tpm_chip *chip = dev_get_drvdata(dev); |
632 | 617 | tpm_chip_unregister(chip); | |
633 | tpm_dev_vendor_release(chip); | ||
634 | tpm_remove_hardware(dev); | ||
635 | kfree(chip); | ||
636 | return 0; | 618 | return 0; |
637 | } | 619 | } |
638 | 620 | ||
639 | |||
640 | static const struct i2c_device_id i2c_nuvoton_id[] = { | 621 | static const struct i2c_device_id i2c_nuvoton_id[] = { |
641 | {I2C_DRIVER_NAME, 0}, | 622 | {I2C_DRIVER_NAME, 0}, |
642 | {} | 623 | {} |
diff --git a/drivers/char/tpm/tpm_i2c_stm_st33.c b/drivers/char/tpm/tpm_i2c_stm_st33.c index 86203b022d13..9a96d3704fe5 100644 --- a/drivers/char/tpm/tpm_i2c_stm_st33.c +++ b/drivers/char/tpm/tpm_i2c_stm_st33.c | |||
@@ -735,11 +735,9 @@ tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
735 | if (!tpm_dev) | 735 | if (!tpm_dev) |
736 | return -ENOMEM; | 736 | return -ENOMEM; |
737 | 737 | ||
738 | chip = tpm_register_hardware(&client->dev, &st_i2c_tpm); | 738 | chip = tpmm_chip_alloc(&client->dev, &st_i2c_tpm); |
739 | if (!chip) { | 739 | if (IS_ERR(chip)) |
740 | dev_info(&client->dev, "fail chip\n"); | 740 | return PTR_ERR(chip); |
741 | return -ENODEV; | ||
742 | } | ||
743 | 741 | ||
744 | TPM_VPRIV(chip) = tpm_dev; | 742 | TPM_VPRIV(chip) = tpm_dev; |
745 | tpm_dev->client = client; | 743 | tpm_dev->client = client; |
@@ -807,10 +805,8 @@ tpm_stm_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
807 | tpm_get_timeouts(chip); | 805 | tpm_get_timeouts(chip); |
808 | tpm_do_selftest(chip); | 806 | tpm_do_selftest(chip); |
809 | 807 | ||
810 | dev_info(chip->dev, "TPM I2C Initialized\n"); | 808 | return tpm_chip_register(chip); |
811 | return 0; | ||
812 | _tpm_clean_answer: | 809 | _tpm_clean_answer: |
813 | tpm_remove_hardware(chip->dev); | ||
814 | dev_info(chip->dev, "TPM I2C initialisation fail\n"); | 810 | dev_info(chip->dev, "TPM I2C initialisation fail\n"); |
815 | return ret; | 811 | return ret; |
816 | } | 812 | } |
@@ -827,7 +823,7 @@ static int tpm_stm_i2c_remove(struct i2c_client *client) | |||
827 | (struct tpm_chip *) i2c_get_clientdata(client); | 823 | (struct tpm_chip *) i2c_get_clientdata(client); |
828 | 824 | ||
829 | if (chip) | 825 | if (chip) |
830 | tpm_remove_hardware(chip->dev); | 826 | tpm_chip_unregister(chip); |
831 | 827 | ||
832 | return 0; | 828 | return 0; |
833 | } | 829 | } |
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 96f5d448b84c..0840347e251c 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c | |||
@@ -270,8 +270,11 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) | |||
270 | static int tpm_ibmvtpm_remove(struct vio_dev *vdev) | 270 | static int tpm_ibmvtpm_remove(struct vio_dev *vdev) |
271 | { | 271 | { |
272 | struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); | 272 | struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); |
273 | struct tpm_chip *chip = dev_get_drvdata(ibmvtpm->dev); | ||
273 | int rc = 0; | 274 | int rc = 0; |
274 | 275 | ||
276 | tpm_chip_unregister(chip); | ||
277 | |||
275 | free_irq(vdev->irq, ibmvtpm); | 278 | free_irq(vdev->irq, ibmvtpm); |
276 | 279 | ||
277 | do { | 280 | do { |
@@ -290,8 +293,6 @@ static int tpm_ibmvtpm_remove(struct vio_dev *vdev) | |||
290 | kfree(ibmvtpm->rtce_buf); | 293 | kfree(ibmvtpm->rtce_buf); |
291 | } | 294 | } |
292 | 295 | ||
293 | tpm_remove_hardware(ibmvtpm->dev); | ||
294 | |||
295 | kfree(ibmvtpm); | 296 | kfree(ibmvtpm); |
296 | 297 | ||
297 | return 0; | 298 | return 0; |
@@ -563,11 +564,9 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, | |||
563 | struct tpm_chip *chip; | 564 | struct tpm_chip *chip; |
564 | int rc = -ENOMEM, rc1; | 565 | int rc = -ENOMEM, rc1; |
565 | 566 | ||
566 | chip = tpm_register_hardware(dev, &tpm_ibmvtpm); | 567 | chip = tpmm_chip_alloc(dev, &tpm_ibmvtpm); |
567 | if (!chip) { | 568 | if (IS_ERR(chip)) |
568 | dev_err(dev, "tpm_register_hardware failed\n"); | 569 | return PTR_ERR(chip); |
569 | return -ENODEV; | ||
570 | } | ||
571 | 570 | ||
572 | ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL); | 571 | ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL); |
573 | if (!ibmvtpm) { | 572 | if (!ibmvtpm) { |
@@ -637,7 +636,7 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, | |||
637 | if (rc) | 636 | if (rc) |
638 | goto init_irq_cleanup; | 637 | goto init_irq_cleanup; |
639 | 638 | ||
640 | return rc; | 639 | return tpm_chip_register(chip); |
641 | init_irq_cleanup: | 640 | init_irq_cleanup: |
642 | do { | 641 | do { |
643 | rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address); | 642 | rc1 = plpar_hcall_norets(H_FREE_CRQ, vio_dev->unit_address); |
@@ -652,8 +651,6 @@ cleanup: | |||
652 | kfree(ibmvtpm); | 651 | kfree(ibmvtpm); |
653 | } | 652 | } |
654 | 653 | ||
655 | tpm_remove_hardware(dev); | ||
656 | |||
657 | return rc; | 654 | return rc; |
658 | } | 655 | } |
659 | 656 | ||
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index dc0a2554034e..dcdb671b2a5d 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -546,7 +546,14 @@ static int tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
546 | vendorid[0], vendorid[1], | 546 | vendorid[0], vendorid[1], |
547 | productid[0], productid[1], chipname); | 547 | productid[0], productid[1], chipname); |
548 | 548 | ||
549 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) | 549 | chip = tpmm_chip_alloc(&dev->dev, &tpm_inf); |
550 | if (IS_ERR(chip)) { | ||
551 | rc = PTR_ERR(chip); | ||
552 | goto err_release_region; | ||
553 | } | ||
554 | |||
555 | rc = tpm_chip_register(chip); | ||
556 | if (rc) | ||
550 | goto err_release_region; | 557 | goto err_release_region; |
551 | 558 | ||
552 | return 0; | 559 | return 0; |
@@ -572,17 +579,15 @@ static void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
572 | { | 579 | { |
573 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 580 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
574 | 581 | ||
575 | if (chip) { | 582 | tpm_chip_unregister(chip); |
576 | if (tpm_dev.iotype == TPM_INF_IO_PORT) { | 583 | |
577 | release_region(tpm_dev.data_regs, tpm_dev.data_size); | 584 | if (tpm_dev.iotype == TPM_INF_IO_PORT) { |
578 | release_region(tpm_dev.config_port, | 585 | release_region(tpm_dev.data_regs, tpm_dev.data_size); |
579 | tpm_dev.config_size); | 586 | release_region(tpm_dev.config_port, |
580 | } else { | 587 | tpm_dev.config_size); |
581 | iounmap(tpm_dev.mem_base); | 588 | } else { |
582 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | 589 | iounmap(tpm_dev.mem_base); |
583 | } | 590 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); |
584 | tpm_dev_vendor_release(chip); | ||
585 | tpm_remove_hardware(chip->dev); | ||
586 | } | 591 | } |
587 | } | 592 | } |
588 | 593 | ||
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 4d0a17ea8cde..6e2c2e64b292 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -247,10 +247,9 @@ static struct platform_device *pdev = NULL; | |||
247 | static void tpm_nsc_remove(struct device *dev) | 247 | static void tpm_nsc_remove(struct device *dev) |
248 | { | 248 | { |
249 | struct tpm_chip *chip = dev_get_drvdata(dev); | 249 | struct tpm_chip *chip = dev_get_drvdata(dev); |
250 | if ( chip ) { | 250 | |
251 | release_region(chip->vendor.base, 2); | 251 | tpm_chip_unregister(chip); |
252 | tpm_remove_hardware(chip->dev); | 252 | release_region(chip->vendor.base, 2); |
253 | } | ||
254 | } | 253 | } |
255 | 254 | ||
256 | static SIMPLE_DEV_PM_OPS(tpm_nsc_pm, tpm_pm_suspend, tpm_pm_resume); | 255 | static SIMPLE_DEV_PM_OPS(tpm_nsc_pm, tpm_pm_suspend, tpm_pm_resume); |
@@ -307,11 +306,16 @@ static int __init init_nsc(void) | |||
307 | goto err_del_dev; | 306 | goto err_del_dev; |
308 | } | 307 | } |
309 | 308 | ||
310 | if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) { | 309 | chip = tpmm_chip_alloc(&pdev->dev, &tpm_nsc); |
310 | if (IS_ERR(chip)) { | ||
311 | rc = -ENODEV; | 311 | rc = -ENODEV; |
312 | goto err_rel_reg; | 312 | goto err_rel_reg; |
313 | } | 313 | } |
314 | 314 | ||
315 | rc = tpm_chip_register(chip); | ||
316 | if (rc) | ||
317 | goto err_rel_reg; | ||
318 | |||
315 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); | 319 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); |
316 | dev_dbg(&pdev->dev, | 320 | dev_dbg(&pdev->dev, |
317 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", | 321 | "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index ccb140d60532..36f4fec11c2a 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -79,9 +79,6 @@ struct priv_data { | |||
79 | bool irq_tested; | 79 | bool irq_tested; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | static LIST_HEAD(tis_chips); | ||
83 | static DEFINE_MUTEX(tis_lock); | ||
84 | |||
85 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) | 82 | #if defined(CONFIG_PNP) && defined(CONFIG_ACPI) |
86 | static int is_itpm(struct pnp_dev *dev) | 83 | static int is_itpm(struct pnp_dev *dev) |
87 | { | 84 | { |
@@ -572,6 +569,17 @@ static bool interrupts = true; | |||
572 | module_param(interrupts, bool, 0444); | 569 | module_param(interrupts, bool, 0444); |
573 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | 570 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); |
574 | 571 | ||
572 | static void tpm_tis_remove(struct tpm_chip *chip) | ||
573 | { | ||
574 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | ||
575 | ioread32(chip->vendor.iobase + | ||
576 | TPM_INT_ENABLE(chip->vendor. | ||
577 | locality)), | ||
578 | chip->vendor.iobase + | ||
579 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
580 | release_locality(chip, chip->vendor.locality, 1); | ||
581 | } | ||
582 | |||
575 | static int tpm_tis_init(struct device *dev, resource_size_t start, | 583 | static int tpm_tis_init(struct device *dev, resource_size_t start, |
576 | resource_size_t len, unsigned int irq) | 584 | resource_size_t len, unsigned int irq) |
577 | { | 585 | { |
@@ -583,15 +591,16 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
583 | priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL); | 591 | priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL); |
584 | if (priv == NULL) | 592 | if (priv == NULL) |
585 | return -ENOMEM; | 593 | return -ENOMEM; |
586 | if (!(chip = tpm_register_hardware(dev, &tpm_tis))) | 594 | |
587 | return -ENODEV; | 595 | chip = tpmm_chip_alloc(dev, &tpm_tis); |
596 | if (IS_ERR(chip)) | ||
597 | return PTR_ERR(chip); | ||
598 | |||
588 | chip->vendor.priv = priv; | 599 | chip->vendor.priv = priv; |
589 | 600 | ||
590 | chip->vendor.iobase = ioremap(start, len); | 601 | chip->vendor.iobase = devm_ioremap(dev, start, len); |
591 | if (!chip->vendor.iobase) { | 602 | if (!chip->vendor.iobase) |
592 | rc = -EIO; | 603 | return -EIO; |
593 | goto out_err; | ||
594 | } | ||
595 | 604 | ||
596 | /* Default timeouts */ | 605 | /* Default timeouts */ |
597 | chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | 606 | chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); |
@@ -685,8 +694,8 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
685 | for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) { | 694 | for (i = irq_s; i <= irq_e && chip->vendor.irq == 0; i++) { |
686 | iowrite8(i, chip->vendor.iobase + | 695 | iowrite8(i, chip->vendor.iobase + |
687 | TPM_INT_VECTOR(chip->vendor.locality)); | 696 | TPM_INT_VECTOR(chip->vendor.locality)); |
688 | if (request_irq | 697 | if (devm_request_irq |
689 | (i, tis_int_probe, IRQF_SHARED, | 698 | (dev, i, tis_int_probe, IRQF_SHARED, |
690 | chip->vendor.miscdev.name, chip) != 0) { | 699 | chip->vendor.miscdev.name, chip) != 0) { |
691 | dev_info(chip->dev, | 700 | dev_info(chip->dev, |
692 | "Unable to request irq: %d for probe\n", | 701 | "Unable to request irq: %d for probe\n", |
@@ -726,15 +735,14 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
726 | iowrite32(intmask, | 735 | iowrite32(intmask, |
727 | chip->vendor.iobase + | 736 | chip->vendor.iobase + |
728 | TPM_INT_ENABLE(chip->vendor.locality)); | 737 | TPM_INT_ENABLE(chip->vendor.locality)); |
729 | free_irq(i, chip); | ||
730 | } | 738 | } |
731 | } | 739 | } |
732 | if (chip->vendor.irq) { | 740 | if (chip->vendor.irq) { |
733 | iowrite8(chip->vendor.irq, | 741 | iowrite8(chip->vendor.irq, |
734 | chip->vendor.iobase + | 742 | chip->vendor.iobase + |
735 | TPM_INT_VECTOR(chip->vendor.locality)); | 743 | TPM_INT_VECTOR(chip->vendor.locality)); |
736 | if (request_irq | 744 | if (devm_request_irq |
737 | (chip->vendor.irq, tis_int_handler, IRQF_SHARED, | 745 | (dev, chip->vendor.irq, tis_int_handler, IRQF_SHARED, |
738 | chip->vendor.miscdev.name, chip) != 0) { | 746 | chip->vendor.miscdev.name, chip) != 0) { |
739 | dev_info(chip->dev, | 747 | dev_info(chip->dev, |
740 | "Unable to request irq: %d for use\n", | 748 | "Unable to request irq: %d for use\n", |
@@ -767,17 +775,9 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, | |||
767 | goto out_err; | 775 | goto out_err; |
768 | } | 776 | } |
769 | 777 | ||
770 | INIT_LIST_HEAD(&chip->vendor.list); | 778 | return tpm_chip_register(chip); |
771 | mutex_lock(&tis_lock); | ||
772 | list_add(&chip->vendor.list, &tis_chips); | ||
773 | mutex_unlock(&tis_lock); | ||
774 | |||
775 | |||
776 | return 0; | ||
777 | out_err: | 779 | out_err: |
778 | if (chip->vendor.iobase) | 780 | tpm_tis_remove(chip); |
779 | iounmap(chip->vendor.iobase); | ||
780 | tpm_remove_hardware(chip->dev); | ||
781 | return rc; | 781 | return rc; |
782 | } | 782 | } |
783 | 783 | ||
@@ -859,13 +859,10 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); | |||
859 | static void tpm_tis_pnp_remove(struct pnp_dev *dev) | 859 | static void tpm_tis_pnp_remove(struct pnp_dev *dev) |
860 | { | 860 | { |
861 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 861 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
862 | 862 | tpm_chip_unregister(chip); | |
863 | tpm_dev_vendor_release(chip); | 863 | tpm_tis_remove(chip); |
864 | |||
865 | kfree(chip); | ||
866 | } | 864 | } |
867 | 865 | ||
868 | |||
869 | static struct pnp_driver tis_pnp_driver = { | 866 | static struct pnp_driver tis_pnp_driver = { |
870 | .name = "tpm_tis", | 867 | .name = "tpm_tis", |
871 | .id_table = tpm_pnp_tbl, | 868 | .id_table = tpm_pnp_tbl, |
@@ -884,7 +881,7 @@ MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | |||
884 | 881 | ||
885 | static struct platform_driver tis_drv = { | 882 | static struct platform_driver tis_drv = { |
886 | .driver = { | 883 | .driver = { |
887 | .name = "tpm_tis", | 884 | .name = "tpm_tis", |
888 | .pm = &tpm_tis_pm, | 885 | .pm = &tpm_tis_pm, |
889 | }, | 886 | }, |
890 | }; | 887 | }; |
@@ -923,31 +920,16 @@ err_dev: | |||
923 | 920 | ||
924 | static void __exit cleanup_tis(void) | 921 | static void __exit cleanup_tis(void) |
925 | { | 922 | { |
926 | struct tpm_vendor_specific *i, *j; | ||
927 | struct tpm_chip *chip; | 923 | struct tpm_chip *chip; |
928 | mutex_lock(&tis_lock); | ||
929 | list_for_each_entry_safe(i, j, &tis_chips, list) { | ||
930 | chip = to_tpm_chip(i); | ||
931 | tpm_remove_hardware(chip->dev); | ||
932 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | ||
933 | ioread32(chip->vendor.iobase + | ||
934 | TPM_INT_ENABLE(chip->vendor. | ||
935 | locality)), | ||
936 | chip->vendor.iobase + | ||
937 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
938 | release_locality(chip, chip->vendor.locality, 1); | ||
939 | if (chip->vendor.irq) | ||
940 | free_irq(chip->vendor.irq, chip); | ||
941 | iounmap(i->iobase); | ||
942 | list_del(&i->list); | ||
943 | } | ||
944 | mutex_unlock(&tis_lock); | ||
945 | #ifdef CONFIG_PNP | 924 | #ifdef CONFIG_PNP |
946 | if (!force) { | 925 | if (!force) { |
947 | pnp_unregister_driver(&tis_pnp_driver); | 926 | pnp_unregister_driver(&tis_pnp_driver); |
948 | return; | 927 | return; |
949 | } | 928 | } |
950 | #endif | 929 | #endif |
930 | chip = dev_get_drvdata(&pdev->dev); | ||
931 | tpm_chip_unregister(chip); | ||
932 | tpm_tis_remove(chip); | ||
951 | platform_device_unregister(pdev); | 933 | platform_device_unregister(pdev); |
952 | platform_driver_unregister(&tis_drv); | 934 | platform_driver_unregister(&tis_drv); |
953 | } | 935 | } |
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 441b44e54226..c3b4f5a5ac10 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c | |||
@@ -175,9 +175,9 @@ static int setup_chip(struct device *dev, struct tpm_private *priv) | |||
175 | { | 175 | { |
176 | struct tpm_chip *chip; | 176 | struct tpm_chip *chip; |
177 | 177 | ||
178 | chip = tpm_register_hardware(dev, &tpm_vtpm); | 178 | chip = tpmm_chip_alloc(dev, &tpm_vtpm); |
179 | if (!chip) | 179 | if (IS_ERR(chip)) |
180 | return -ENODEV; | 180 | return PTR_ERR(chip); |
181 | 181 | ||
182 | init_waitqueue_head(&chip->vendor.read_queue); | 182 | init_waitqueue_head(&chip->vendor.read_queue); |
183 | 183 | ||
@@ -286,6 +286,7 @@ static int tpmfront_probe(struct xenbus_device *dev, | |||
286 | const struct xenbus_device_id *id) | 286 | const struct xenbus_device_id *id) |
287 | { | 287 | { |
288 | struct tpm_private *priv; | 288 | struct tpm_private *priv; |
289 | struct tpm_chip *chip; | ||
289 | int rv; | 290 | int rv; |
290 | 291 | ||
291 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 292 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
@@ -302,21 +303,22 @@ static int tpmfront_probe(struct xenbus_device *dev, | |||
302 | 303 | ||
303 | rv = setup_ring(dev, priv); | 304 | rv = setup_ring(dev, priv); |
304 | if (rv) { | 305 | if (rv) { |
305 | tpm_remove_hardware(&dev->dev); | 306 | chip = dev_get_drvdata(&dev->dev); |
307 | tpm_chip_unregister(chip); | ||
306 | ring_free(priv); | 308 | ring_free(priv); |
307 | return rv; | 309 | return rv; |
308 | } | 310 | } |
309 | 311 | ||
310 | tpm_get_timeouts(priv->chip); | 312 | tpm_get_timeouts(priv->chip); |
311 | 313 | ||
312 | return rv; | 314 | return tpm_chip_register(priv->chip); |
313 | } | 315 | } |
314 | 316 | ||
315 | static int tpmfront_remove(struct xenbus_device *dev) | 317 | static int tpmfront_remove(struct xenbus_device *dev) |
316 | { | 318 | { |
317 | struct tpm_chip *chip = dev_get_drvdata(&dev->dev); | 319 | struct tpm_chip *chip = dev_get_drvdata(&dev->dev); |
318 | struct tpm_private *priv = TPM_VPRIV(chip); | 320 | struct tpm_private *priv = TPM_VPRIV(chip); |
319 | tpm_remove_hardware(&dev->dev); | 321 | tpm_chip_unregister(chip); |
320 | ring_free(priv); | 322 | ring_free(priv); |
321 | TPM_VPRIV(chip) = NULL; | 323 | TPM_VPRIV(chip) = NULL; |
322 | return 0; | 324 | return 0; |