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 <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 * tpm_chip_find_get - return tpm_chip for a given chip number 41 * @chip_num the device number for the chip 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 * tpm_dev_release() - free chip memory and the device number 63 * @dev: the character device for the TPM chip 64 * 65 * This is used as the release function for the character device. 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 * tpmm_chip_alloc() - allocate a new struct tpm_chip instance 79 * @dev: device to which the chip is associated 80 * @ops: struct tpm_class_ops instance 81 * 82 * Allocates a new struct tpm_chip instance and assigns a free 83 * device number for it. Caller does not have to worry about 84 * freeing the allocated resources. When the devices is removed 85 * devres calls tpmm_chip_remove() to do the job. 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#ifdef CONFIG_ACPI 123 chip->dev.groups = chip->groups; 124#endif 125 126 if (chip->dev_num == 0) 127 chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR); 128 else 129 chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num); 130 131 dev_set_name(&chip->dev, "%s", chip->devname); 132 133 device_initialize(&chip->dev); 134 135 cdev_init(&chip->cdev, &tpm_fops); 136 chip->cdev.owner = chip->pdev->driver->owner; 137 chip->cdev.kobj.parent = &chip->dev.kobj; 138 139 devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev); 140 141 return chip; 142} 143EXPORT_SYMBOL_GPL(tpmm_chip_alloc); 144 145static int tpm_add_char_device(struct tpm_chip *chip) 146{ 147 int rc; 148 149 rc = cdev_add(&chip->cdev, chip->dev.devt, 1); 150 if (rc) { 151 dev_err(&chip->dev, 152 "unable to cdev_add() %s, major %d, minor %d, err=%d\n", 153 chip->devname, MAJOR(chip->dev.devt), 154 MINOR(chip->dev.devt), rc); 155 156 return rc; 157 } 158 159 rc = device_add(&chip->dev); 160 if (rc) { 161 dev_err(&chip->dev, 162 "unable to device_register() %s, major %d, minor %d, err=%d\n", 163 chip->devname, MAJOR(chip->dev.devt), 164 MINOR(chip->dev.devt), rc); 165 166 cdev_del(&chip->cdev); 167 return rc; 168 } 169 170 return rc; 171} 172 173static void tpm_del_char_device(struct tpm_chip *chip) 174{ 175 cdev_del(&chip->cdev); 176 device_del(&chip->dev); 177} 178 179static int tpm1_chip_register(struct tpm_chip *chip) 180{ 181 int rc; 182 183 if (chip->flags & TPM_CHIP_FLAG_TPM2) 184 return 0; 185 186 rc = tpm_sysfs_add_device(chip); 187 if (rc) 188 return rc; 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_sysfs_del_device(chip); 204} 205 206/* 207 * tpm_chip_register() - create a character device for the TPM chip 208 * @chip: TPM chip to use. 209 * 210 * Creates a character device for the TPM chip and adds sysfs attributes for 211 * the device. As the last step this function adds the chip to the list of TPM 212 * chips available for in-kernel use. 213 * 214 * This function should be only called after the chip initialization is 215 * complete. 216 */ 217int tpm_chip_register(struct tpm_chip *chip) 218{ 219 int rc; 220 221 rc = tpm1_chip_register(chip); 222 if (rc) 223 return rc; 224 225 tpm_add_ppi(chip); 226 227 rc = tpm_add_char_device(chip); 228 if (rc) 229 goto out_err; 230 231 /* Make the chip available. */ 232 spin_lock(&driver_lock); 233 list_add_tail_rcu(&chip->list, &tpm_chip_list); 234 spin_unlock(&driver_lock); 235 236 chip->flags |= TPM_CHIP_FLAG_REGISTERED; 237 238 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) { 239 rc = __compat_only_sysfs_link_entry_to_kobj(&chip->pdev->kobj, 240 &chip->dev.kobj, 241 "ppi"); 242 if (rc && rc != -ENOENT) { 243 tpm_chip_unregister(chip); 244 return rc; 245 } 246 } 247 248 return 0; 249out_err: 250 tpm1_chip_unregister(chip); 251 return rc; 252} 253EXPORT_SYMBOL_GPL(tpm_chip_register); 254 255/* 256 * tpm_chip_unregister() - release the TPM driver 257 * @chip: TPM chip to use. 258 * 259 * Takes the chip first away from the list of available TPM chips and then 260 * cleans up all the resources reserved by tpm_chip_register(). 261 * 262 * NOTE: This function should be only called before deinitializing chip 263 * resources. 264 */ 265void tpm_chip_unregister(struct tpm_chip *chip) 266{ 267 if (!(chip->flags & TPM_CHIP_FLAG_REGISTERED)) 268 return; 269 270 spin_lock(&driver_lock); 271 list_del_rcu(&chip->list); 272 spin_unlock(&driver_lock); 273 synchronize_rcu(); 274 275 if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) 276 sysfs_remove_link(&chip->pdev->kobj, "ppi"); 277 278 tpm1_chip_unregister(chip); 279 tpm_del_char_device(chip); 280} 281EXPORT_SYMBOL_GPL(tpm_chip_unregister); 282