1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 <linux/major.h>
29#include "tpm.h"
30#include "tpm_eventlog.h"
31
32static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
33static LIST_HEAD(tpm_chip_list);
34static DEFINE_SPINLOCK(driver_lock);
35
36struct class *tpm_class;
37dev_t tpm_devt;
38
39
40
41
42
43struct tpm_chip *tpm_chip_find_get(int chip_num)
44{
45 struct tpm_chip *pos, *chip = NULL;
46
47 rcu_read_lock();
48 list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
49 if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
50 continue;
51
52 if (try_module_get(pos->pdev->driver->owner)) {
53 chip = pos;
54 break;
55 }
56 }
57 rcu_read_unlock();
58 return chip;
59}
60
61
62
63
64
65
66
67static void tpm_dev_release(struct device *dev)
68{
69 struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
70
71 spin_lock(&driver_lock);
72 clear_bit(chip->dev_num, dev_mask);
73 spin_unlock(&driver_lock);
74 kfree(chip);
75}
76
77
78
79
80
81
82
83
84
85
86
87struct tpm_chip *tpmm_chip_alloc(struct device *dev,
88 const struct tpm_class_ops *ops)
89{
90 struct tpm_chip *chip;
91
92 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
93 if (chip == NULL)
94 return ERR_PTR(-ENOMEM);
95
96 mutex_init(&chip->tpm_mutex);
97 INIT_LIST_HEAD(&chip->list);
98
99 chip->ops = ops;
100
101 spin_lock(&driver_lock);
102 chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
103 spin_unlock(&driver_lock);
104
105 if (chip->dev_num >= TPM_NUM_DEVICES) {
106 dev_err(dev, "No available tpm device numbers\n");
107 kfree(chip);
108 return ERR_PTR(-ENOMEM);
109 }
110
111 set_bit(chip->dev_num, dev_mask);
112
113 scnprintf(chip->devname, sizeof(chip->devname), "tpm%d", chip->dev_num);
114
115 chip->pdev = dev;
116
117 dev_set_drvdata(dev, chip);
118
119 chip->dev.class = tpm_class;
120 chip->dev.release = tpm_dev_release;
121 chip->dev.parent = chip->pdev;
122
123 if (chip->dev_num == 0)
124 chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
125 else
126 chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
127
128 dev_set_name(&chip->dev, "%s", chip->devname);
129
130 device_initialize(&chip->dev);
131
132 chip->cdev.owner = chip->pdev->driver->owner;
133 cdev_init(&chip->cdev, &tpm_fops);
134
135 return chip;
136}
137EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
138
139static int tpm_dev_add_device(struct tpm_chip *chip)
140{
141 int rc;
142
143 rc = cdev_add(&chip->cdev, chip->dev.devt, 1);
144 if (rc) {
145 dev_err(&chip->dev,
146 "unable to cdev_add() %s, major %d, minor %d, err=%d\n",
147 chip->devname, MAJOR(chip->dev.devt),
148 MINOR(chip->dev.devt), rc);
149
150 device_unregister(&chip->dev);
151 return rc;
152 }
153
154 rc = device_add(&chip->dev);
155 if (rc) {
156 dev_err(&chip->dev,
157 "unable to device_register() %s, major %d, minor %d, err=%d\n",
158 chip->devname, MAJOR(chip->dev.devt),
159 MINOR(chip->dev.devt), rc);
160
161 return rc;
162 }
163
164 return rc;
165}
166
167static void tpm_dev_del_device(struct tpm_chip *chip)
168{
169 cdev_del(&chip->cdev);
170 device_unregister(&chip->dev);
171}
172
173static int tpm1_chip_register(struct tpm_chip *chip)
174{
175 int rc;
176
177 if (chip->flags & TPM_CHIP_FLAG_TPM2)
178 return 0;
179
180 rc = tpm_sysfs_add_device(chip);
181 if (rc)
182 return rc;
183
184 rc = tpm_add_ppi(chip);
185 if (rc) {
186 tpm_sysfs_del_device(chip);
187 return rc;
188 }
189
190 chip->bios_dir = tpm_bios_log_setup(chip->devname);
191
192 return 0;
193}
194
195static void tpm1_chip_unregister(struct tpm_chip *chip)
196{
197 if (chip->flags & TPM_CHIP_FLAG_TPM2)
198 return;
199
200 if (chip->bios_dir)
201 tpm_bios_log_teardown(chip->bios_dir);
202
203 tpm_remove_ppi(chip);
204
205 tpm_sysfs_del_device(chip);
206}
207
208
209
210
211
212
213
214
215
216
217
218
219int tpm_chip_register(struct tpm_chip *chip)
220{
221 int rc;
222
223 rc = tpm1_chip_register(chip);
224 if (rc)
225 return rc;
226
227 rc = tpm_dev_add_device(chip);
228 if (rc)
229 goto out_err;
230
231
232 spin_lock(&driver_lock);
233 list_add_rcu(&chip->list, &tpm_chip_list);
234 spin_unlock(&driver_lock);
235
236 chip->flags |= TPM_CHIP_FLAG_REGISTERED;
237
238 return 0;
239out_err:
240 tpm1_chip_unregister(chip);
241 return rc;
242}
243EXPORT_SYMBOL_GPL(tpm_chip_register);
244
245
246
247
248
249
250
251
252
253
254
255void tpm_chip_unregister(struct tpm_chip *chip)
256{
257 if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED))
258 return;
259
260 spin_lock(&driver_lock);
261 list_del_rcu(&chip->list);
262 spin_unlock(&driver_lock);
263 synchronize_rcu();
264
265 tpm1_chip_unregister(chip);
266 tpm_dev_del_device(chip);
267}
268EXPORT_SYMBOL_GPL(tpm_chip_unregister);
269