blob: 242b716aed5e51f55d08d615f1b0e9b0851e6d94 [file] [log] [blame]
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -08001/*
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>
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -080028#include <linux/major.h>
Thiebaud Weksteenfd3ec362017-09-20 10:13:36 +020029#include <linux/tpm_eventlog.h>
Jason Gunthorpe6e592a02017-11-17 15:24:03 +020030#include <linux/hw_random.h>
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -080031#include "tpm.h"
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -080032
Stefan Berger15516782016-02-29 08:53:02 -050033DEFINE_IDR(dev_nums_idr);
34static DEFINE_MUTEX(idr_lock);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -080035
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -080036struct class *tpm_class;
James Bottomleyfdc915f2017-01-03 09:07:32 -080037struct class *tpmrm_class;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -080038dev_t tpm_devt;
39
Jason Gunthorpe4e261952016-02-12 20:29:53 -070040/**
41 * tpm_try_get_ops() - Get a ref to the tpm_chip
42 * @chip: Chip to ref
43 *
44 * The caller must already have some kind of locking to ensure that chip is
45 * valid. This function will lock the chip so that the ops member can be
46 * accessed safely. The locking prevents tpm_chip_unregister from
47 * completing, so it should not be held for long periods.
48 *
49 * Returns -ERRNO if the chip could not be got.
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -080050 */
Jason Gunthorpe4e261952016-02-12 20:29:53 -070051int tpm_try_get_ops(struct tpm_chip *chip)
52{
53 int rc = -EIO;
54
55 get_device(&chip->dev);
56
57 down_read(&chip->ops_sem);
58 if (!chip->ops)
59 goto out_lock;
60
Jason Gunthorpe4e261952016-02-12 20:29:53 -070061 return 0;
62out_lock:
63 up_read(&chip->ops_sem);
64 put_device(&chip->dev);
65 return rc;
66}
67EXPORT_SYMBOL_GPL(tpm_try_get_ops);
68
69/**
70 * tpm_put_ops() - Release a ref to the tpm_chip
71 * @chip: Chip to put
72 *
73 * This is the opposite pair to tpm_try_get_ops(). After this returns chip may
74 * be kfree'd.
75 */
76void tpm_put_ops(struct tpm_chip *chip)
77{
Jason Gunthorpe4e261952016-02-12 20:29:53 -070078 up_read(&chip->ops_sem);
79 put_device(&chip->dev);
80}
81EXPORT_SYMBOL_GPL(tpm_put_ops);
82
83/**
Stefan Bergerfc1d52b2018-06-26 07:06:15 -040084 * tpm_find_get_ops() - find and reserve a TPM chip
Jarkko Sakkinenaad887f2017-11-05 13:16:26 +020085 * @chip: a &struct tpm_chip instance, %NULL for the default chip
Jason Gunthorpe4e261952016-02-12 20:29:53 -070086 *
Jarkko Sakkinenaad887f2017-11-05 13:16:26 +020087 * Finds a TPM chip and reserves its class device and operations. The chip must
Stefan Bergerfc1d52b2018-06-26 07:06:15 -040088 * be released with tpm_put_ops() after use.
89 * This function is for internal use only. It supports existing TPM callers
90 * by accepting NULL, but those callers should be converted to pass in a chip
91 * directly.
Jarkko Sakkinenaad887f2017-11-05 13:16:26 +020092 *
93 * Return:
94 * A reserved &struct tpm_chip instance.
95 * %NULL if a chip is not found.
96 * %NULL if the chip is not available.
Matthew Wilcox37f49152016-12-14 15:09:16 -080097 */
Stefan Bergerfc1d52b2018-06-26 07:06:15 -040098struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip)
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -080099{
Jarkko Sakkinenaad887f2017-11-05 13:16:26 +0200100 struct tpm_chip *res = NULL;
101 int chip_num = 0;
Stefan Berger15516782016-02-29 08:53:02 -0500102 int chip_prev;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800103
Stefan Berger15516782016-02-29 08:53:02 -0500104 mutex_lock(&idr_lock);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800105
Jarkko Sakkinenaad887f2017-11-05 13:16:26 +0200106 if (!chip) {
Stefan Berger15516782016-02-29 08:53:02 -0500107 do {
108 chip_prev = chip_num;
109 chip = idr_get_next(&dev_nums_idr, &chip_num);
110 if (chip && !tpm_try_get_ops(chip)) {
111 res = chip;
112 break;
113 }
114 } while (chip_prev != chip_num);
115 } else {
Jarkko Sakkinenaad887f2017-11-05 13:16:26 +0200116 if (!tpm_try_get_ops(chip))
Stefan Berger15516782016-02-29 08:53:02 -0500117 res = chip;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800118 }
Stefan Berger15516782016-02-29 08:53:02 -0500119
120 mutex_unlock(&idr_lock);
121
122 return res;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800123}
124
125/**
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800126 * tpm_dev_release() - free chip memory and the device number
127 * @dev: the character device for the TPM chip
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800128 *
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800129 * This is used as the release function for the character device.
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800130 */
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800131static void tpm_dev_release(struct device *dev)
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800132{
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800133 struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800134
Stefan Berger15516782016-02-29 08:53:02 -0500135 mutex_lock(&idr_lock);
136 idr_remove(&dev_nums_idr, chip->dev_num);
137 mutex_unlock(&idr_lock);
138
Nayna Jain748935e2016-11-14 05:00:52 -0500139 kfree(chip->log.bios_event_log);
Jarkko Sakkinen745b3612017-01-06 14:03:45 +0200140 kfree(chip->work_space.context_buf);
James Bottomley4d578562017-01-31 15:47:31 -0800141 kfree(chip->work_space.session_buf);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800142 kfree(chip);
143}
144
James Bottomleyfdc915f2017-01-03 09:07:32 -0800145static void tpm_devs_release(struct device *dev)
146{
147 struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
148
149 /* release the master device reference */
150 put_device(&chip->dev);
151}
152
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800153/**
Josh Zimmermand1bd4a72017-06-25 14:53:24 -0700154 * tpm_class_shutdown() - prepare the TPM device for loss of power.
155 * @dev: device to which the chip is associated.
156 *
157 * Issues a TPM2_Shutdown command prior to loss of power, as required by the
158 * TPM 2.0 spec.
159 * Then, calls bus- and device- specific shutdown code.
160 *
161 * XXX: This codepath relies on the fact that sysfs is not enabled for
162 * TPM2: sysfs uses an implicit lock on chip->ops, so this could race if TPM2
163 * has sysfs support enabled before TPM sysfs's implicit locking is fixed.
164 */
165static int tpm_class_shutdown(struct device *dev)
166{
167 struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
168
169 if (chip->flags & TPM_CHIP_FLAG_TPM2) {
170 down_write(&chip->ops_sem);
171 tpm2_shutdown(chip, TPM2_SU_CLEAR);
172 chip->ops = NULL;
173 up_write(&chip->ops_sem);
174 }
Michal Suchanek75216212017-08-11 15:44:43 +0200175
Josh Zimmermand1bd4a72017-06-25 14:53:24 -0700176 return 0;
177}
178
179/**
Jason Gunthorpe3897cd92016-02-11 12:45:48 -0700180 * tpm_chip_alloc() - allocate a new struct tpm_chip instance
181 * @pdev: device to which the chip is associated
182 * At this point pdev mst be initialized, but does not have to
183 * be registered
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800184 * @ops: struct tpm_class_ops instance
185 *
186 * Allocates a new struct tpm_chip instance and assigns a free
Jason Gunthorpe3897cd92016-02-11 12:45:48 -0700187 * device number for it. Must be paired with put_device(&chip->dev).
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800188 */
Winkler, Tomas2998b022016-11-23 12:04:13 +0200189struct tpm_chip *tpm_chip_alloc(struct device *pdev,
Jason Gunthorpe3897cd92016-02-11 12:45:48 -0700190 const struct tpm_class_ops *ops)
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800191{
192 struct tpm_chip *chip;
Jarkko Sakkinen4f3b1932016-02-13 11:58:16 +0200193 int rc;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800194
195 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
196 if (chip == NULL)
197 return ERR_PTR(-ENOMEM);
198
199 mutex_init(&chip->tpm_mutex);
Jason Gunthorpe4e261952016-02-12 20:29:53 -0700200 init_rwsem(&chip->ops_sem);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800201
202 chip->ops = ops;
203
Stefan Berger15516782016-02-29 08:53:02 -0500204 mutex_lock(&idr_lock);
205 rc = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL);
206 mutex_unlock(&idr_lock);
207 if (rc < 0) {
Winkler, Tomas2998b022016-11-23 12:04:13 +0200208 dev_err(pdev, "No available tpm device numbers\n");
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800209 kfree(chip);
Stefan Berger15516782016-02-29 08:53:02 -0500210 return ERR_PTR(rc);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800211 }
Stefan Berger15516782016-02-29 08:53:02 -0500212 chip->dev_num = rc;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800213
Jason Gunthorpe3635e2e2016-02-29 12:29:48 -0500214 device_initialize(&chip->dev);
James Bottomleyfdc915f2017-01-03 09:07:32 -0800215 device_initialize(&chip->devs);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800216
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800217 chip->dev.class = tpm_class;
Michal Suchanek75216212017-08-11 15:44:43 +0200218 chip->dev.class->shutdown_pre = tpm_class_shutdown;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800219 chip->dev.release = tpm_dev_release;
Winkler, Tomas2998b022016-11-23 12:04:13 +0200220 chip->dev.parent = pdev;
Jarkko Sakkinen9b774d52015-04-14 17:56:48 +0300221 chip->dev.groups = chip->groups;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800222
James Bottomleyfdc915f2017-01-03 09:07:32 -0800223 chip->devs.parent = pdev;
224 chip->devs.class = tpmrm_class;
225 chip->devs.release = tpm_devs_release;
226 /* get extra reference on main device to hold on
227 * behalf of devs. This holds the chip structure
228 * while cdevs is in use. The corresponding put
Stefan Berger8979b022017-04-17 21:58:26 -0400229 * is in the tpm_devs_release (TPM2 only)
James Bottomleyfdc915f2017-01-03 09:07:32 -0800230 */
Stefan Berger8979b022017-04-17 21:58:26 -0400231 if (chip->flags & TPM_CHIP_FLAG_TPM2)
232 get_device(&chip->dev);
James Bottomleyfdc915f2017-01-03 09:07:32 -0800233
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800234 if (chip->dev_num == 0)
235 chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
236 else
237 chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
238
James Bottomleyfdc915f2017-01-03 09:07:32 -0800239 chip->devs.devt =
240 MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
241
Jason Gunthorpe3635e2e2016-02-29 12:29:48 -0500242 rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
243 if (rc)
244 goto out;
James Bottomleyfdc915f2017-01-03 09:07:32 -0800245 rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
246 if (rc)
247 goto out;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800248
Winkler, Tomas2998b022016-11-23 12:04:13 +0200249 if (!pdev)
Stefan Berger2f9f5372016-04-18 13:26:14 -0400250 chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
251
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800252 cdev_init(&chip->cdev, &tpm_fops);
James Bottomleyfdc915f2017-01-03 09:07:32 -0800253 cdev_init(&chip->cdevs, &tpmrm_fops);
Stefan Berger2072df42016-02-29 08:53:01 -0500254 chip->cdev.owner = THIS_MODULE;
James Bottomleyfdc915f2017-01-03 09:07:32 -0800255 chip->cdevs.owner = THIS_MODULE;
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800256
Jarkko Sakkinen745b3612017-01-06 14:03:45 +0200257 chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
258 if (!chip->work_space.context_buf) {
259 rc = -ENOMEM;
260 goto out;
261 }
James Bottomley4d578562017-01-31 15:47:31 -0800262 chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
263 if (!chip->work_space.session_buf) {
264 rc = -ENOMEM;
265 goto out;
266 }
Jarkko Sakkinen745b3612017-01-06 14:03:45 +0200267
Jarkko Sakkinen877c57d2017-03-24 11:45:49 +0200268 chip->locality = -1;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800269 return chip;
Jason Gunthorpe3635e2e2016-02-29 12:29:48 -0500270
271out:
James Bottomleyfdc915f2017-01-03 09:07:32 -0800272 put_device(&chip->devs);
Jason Gunthorpe3635e2e2016-02-29 12:29:48 -0500273 put_device(&chip->dev);
274 return ERR_PTR(rc);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800275}
Jason Gunthorpe3897cd92016-02-11 12:45:48 -0700276EXPORT_SYMBOL_GPL(tpm_chip_alloc);
277
278/**
279 * tpmm_chip_alloc() - allocate a new struct tpm_chip instance
280 * @pdev: parent device to which the chip is associated
281 * @ops: struct tpm_class_ops instance
282 *
283 * Same as tpm_chip_alloc except devm is used to do the put_device
284 */
285struct tpm_chip *tpmm_chip_alloc(struct device *pdev,
286 const struct tpm_class_ops *ops)
287{
288 struct tpm_chip *chip;
289 int rc;
290
291 chip = tpm_chip_alloc(pdev, ops);
292 if (IS_ERR(chip))
293 return chip;
294
Sudip Mukherjee2b88cd92016-06-12 15:05:29 +0100295 rc = devm_add_action_or_reset(pdev,
296 (void (*)(void *)) put_device,
297 &chip->dev);
298 if (rc)
Jason Gunthorpe3897cd92016-02-11 12:45:48 -0700299 return ERR_PTR(rc);
Jason Gunthorpe3897cd92016-02-11 12:45:48 -0700300
301 dev_set_drvdata(pdev, chip);
302
303 return chip;
304}
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800305EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
306
Jarkko Sakkinen72c91ce2016-01-29 09:47:22 -0800307static int tpm_add_char_device(struct tpm_chip *chip)
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800308{
309 int rc;
310
Logan Gunthorpe8dbbf582017-03-17 12:48:13 -0600311 rc = cdev_device_add(&chip->cdev, &chip->dev);
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800312 if (rc) {
313 dev_err(&chip->dev,
Logan Gunthorpe8dbbf582017-03-17 12:48:13 -0600314 "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
Jason Gunthorpe3635e2e2016-02-29 12:29:48 -0500315 dev_name(&chip->dev), MAJOR(chip->dev.devt),
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800316 MINOR(chip->dev.devt), rc);
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800317 return rc;
318 }
319
Linus Torvaldsaf824552017-05-04 19:07:10 -0700320 if (chip->flags & TPM_CHIP_FLAG_TPM2) {
321 rc = cdev_device_add(&chip->cdevs, &chip->devs);
322 if (rc) {
323 dev_err(&chip->devs,
324 "unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
325 dev_name(&chip->devs), MAJOR(chip->devs.devt),
326 MINOR(chip->devs.devt), rc);
327 return rc;
328 }
James Bottomleyfdc915f2017-01-03 09:07:32 -0800329 }
330
Stefan Berger15516782016-02-29 08:53:02 -0500331 /* Make the chip available. */
332 mutex_lock(&idr_lock);
333 idr_replace(&dev_nums_idr, chip, chip->dev_num);
334 mutex_unlock(&idr_lock);
335
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800336 return rc;
337}
338
Jarkko Sakkinen72c91ce2016-01-29 09:47:22 -0800339static void tpm_del_char_device(struct tpm_chip *chip)
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800340{
Logan Gunthorpe8dbbf582017-03-17 12:48:13 -0600341 cdev_device_del(&chip->cdev, &chip->dev);
Stefan Berger15516782016-02-29 08:53:02 -0500342
343 /* Make the chip unavailable. */
344 mutex_lock(&idr_lock);
345 idr_replace(&dev_nums_idr, NULL, chip->dev_num);
346 mutex_unlock(&idr_lock);
Jason Gunthorpe4e261952016-02-12 20:29:53 -0700347
348 /* Make the driver uncallable. */
349 down_write(&chip->ops_sem);
Jarkko Sakkinenc0dff1f2016-04-25 12:20:07 +0300350 if (chip->flags & TPM_CHIP_FLAG_TPM2)
351 tpm2_shutdown(chip, TPM2_SU_CLEAR);
Jason Gunthorpe4e261952016-02-12 20:29:53 -0700352 chip->ops = NULL;
353 up_write(&chip->ops_sem);
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800354}
355
Jason Gunthorpe062807f2016-04-18 13:26:13 -0400356static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
357{
358 struct attribute **i;
359
Stefan Berger2f9f5372016-04-18 13:26:14 -0400360 if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))
Jason Gunthorpe062807f2016-04-18 13:26:13 -0400361 return;
362
363 sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
364
365 for (i = chip->groups[0]->attrs; *i != NULL; ++i)
366 sysfs_remove_link(&chip->dev.parent->kobj, (*i)->name);
367}
368
369/* For compatibility with legacy sysfs paths we provide symlinks from the
370 * parent dev directory to selected names within the tpm chip directory. Old
371 * kernel versions created these files directly under the parent.
372 */
373static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
374{
375 struct attribute **i;
376 int rc;
377
Stefan Berger2f9f5372016-04-18 13:26:14 -0400378 if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))
Jason Gunthorpe062807f2016-04-18 13:26:13 -0400379 return 0;
380
381 rc = __compat_only_sysfs_link_entry_to_kobj(
382 &chip->dev.parent->kobj, &chip->dev.kobj, "ppi");
383 if (rc && rc != -ENOENT)
384 return rc;
385
386 /* All the names from tpm-sysfs */
387 for (i = chip->groups[0]->attrs; *i != NULL; ++i) {
388 rc = __compat_only_sysfs_link_entry_to_kobj(
389 &chip->dev.parent->kobj, &chip->dev.kobj, (*i)->name);
390 if (rc) {
391 tpm_del_legacy_sysfs(chip);
392 return rc;
393 }
394 }
395
396 return 0;
397}
Jason Gunthorpe6e592a02017-11-17 15:24:03 +0200398
399static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
400{
401 struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
402
403 return tpm_get_random(chip, data, max);
404}
405
406static int tpm_add_hwrng(struct tpm_chip *chip)
407{
408 if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM))
409 return 0;
410
411 snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
412 "tpm-rng-%d", chip->dev_num);
413 chip->hwrng.name = chip->hwrng_name;
414 chip->hwrng.read = tpm_hwrng_read;
415 return hwrng_register(&chip->hwrng);
416}
417
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800418/*
Jarkko Sakkinen313d21e2014-12-12 11:46:37 -0800419 * tpm_chip_register() - create a character device for the TPM chip
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800420 * @chip: TPM chip to use.
421 *
Jarkko Sakkinend972b052015-03-01 23:55:47 +0200422 * Creates a character device for the TPM chip and adds sysfs attributes for
423 * the device. As the last step this function adds the chip to the list of TPM
424 * chips available for in-kernel use.
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800425 *
Jarkko Sakkinend972b052015-03-01 23:55:47 +0200426 * This function should be only called after the chip initialization is
427 * complete.
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800428 */
429int tpm_chip_register(struct tpm_chip *chip)
430{
431 int rc;
432
Jason Gunthorpecae8b442016-07-12 11:41:49 -0600433 if (chip->ops->flags & TPM_OPS_AUTO_STARTUP) {
434 if (chip->flags & TPM_CHIP_FLAG_TPM2)
435 rc = tpm2_auto_startup(chip);
436 else
437 rc = tpm1_auto_startup(chip);
438 if (rc)
439 return rc;
440 }
441
Jarkko Sakkinen7518a212016-11-14 05:00:51 -0500442 tpm_sysfs_add_device(chip);
443
444 rc = tpm_bios_log_setup(chip);
Jason Gunthorpe0cf577a2016-11-19 11:18:28 -0700445 if (rc != 0 && rc != -ENODEV)
Jarkko Sakkinen34d47b62015-03-18 08:17:14 +0200446 return rc;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800447
Jarkko Sakkinen9b774d52015-04-14 17:56:48 +0300448 tpm_add_ppi(chip);
449
Jason Gunthorpe6e592a02017-11-17 15:24:03 +0200450 rc = tpm_add_hwrng(chip);
451 if (rc)
452 goto out_ppi;
453
Jarkko Sakkinen72c91ce2016-01-29 09:47:22 -0800454 rc = tpm_add_char_device(chip);
Jason Gunthorpe6e592a02017-11-17 15:24:03 +0200455 if (rc)
456 goto out_hwrng;
Jarkko Sakkinend972b052015-03-01 23:55:47 +0200457
Jason Gunthorpe062807f2016-04-18 13:26:13 -0400458 rc = tpm_add_legacy_sysfs(chip);
459 if (rc) {
460 tpm_chip_unregister(chip);
461 return rc;
Jarkko Sakkinend56e4f72015-11-07 13:33:25 +0200462 }
463
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800464 return 0;
Jason Gunthorpe6e592a02017-11-17 15:24:03 +0200465
466out_hwrng:
467 if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
468 hwrng_unregister(&chip->hwrng);
469out_ppi:
470 tpm_bios_log_teardown(chip);
471
472 return rc;
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800473}
474EXPORT_SYMBOL_GPL(tpm_chip_register);
475
476/*
477 * tpm_chip_unregister() - release the TPM driver
478 * @chip: TPM chip to use.
479 *
480 * Takes the chip first away from the list of available TPM chips and then
481 * cleans up all the resources reserved by tpm_chip_register().
482 *
Jason Gunthorpe4e261952016-02-12 20:29:53 -0700483 * Once this function returns the driver call backs in 'op's will not be
484 * running and will no longer start.
485 *
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800486 * NOTE: This function should be only called before deinitializing chip
487 * resources.
488 */
489void tpm_chip_unregister(struct tpm_chip *chip)
490{
Jason Gunthorpe062807f2016-04-18 13:26:13 -0400491 tpm_del_legacy_sysfs(chip);
Jason Gunthorpe6e592a02017-11-17 15:24:03 +0200492 if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
493 hwrng_unregister(&chip->hwrng);
Jarkko Sakkinen7518a212016-11-14 05:00:51 -0500494 tpm_bios_log_teardown(chip);
Linus Torvaldsaf824552017-05-04 19:07:10 -0700495 if (chip->flags & TPM_CHIP_FLAG_TPM2)
496 cdev_device_del(&chip->cdevs, &chip->devs);
Jarkko Sakkinen72c91ce2016-01-29 09:47:22 -0800497 tpm_del_char_device(chip);
Jarkko Sakkinenafb5abc2014-12-12 11:46:34 -0800498}
499EXPORT_SYMBOL_GPL(tpm_chip_unregister);