#include <linux/hw_random.h>
#include "tpm.h"
-DEFINE_IDR(dev_nums_idr);
-static DEFINE_MUTEX(idr_lock);
+static DEFINE_XARRAY_ALLOC(dev_nums);
struct class *tpm_class;
struct class *tpmrm_class;
*/
struct tpm_chip *tpm_default_chip(void)
{
- struct tpm_chip *chip, *res = NULL;
- int chip_num = 0;
- int chip_prev;
-
- mutex_lock(&idr_lock);
-
- do {
- chip_prev = chip_num;
- chip = idr_get_next(&dev_nums_idr, &chip_num);
- if (chip) {
- get_device(&chip->dev);
- res = chip;
- break;
- }
- } while (chip_prev != chip_num);
+ struct tpm_chip *chip;
+ unsigned long chip_num = 0;
- mutex_unlock(&idr_lock);
+ xa_lock(&dev_nums);
+ chip = xa_find(&dev_nums, &chip_num, ULONG_MAX, XA_PRESENT);
+ if (chip)
+ get_device(&chip->dev);
+ xa_unlock(&dev_nums);
- return res;
+ return chip;
}
EXPORT_SYMBOL_GPL(tpm_default_chip);
{
struct tpm_chip *chip = container_of(dev, struct tpm_chip, dev);
- mutex_lock(&idr_lock);
- idr_remove(&dev_nums_idr, chip->dev_num);
- mutex_unlock(&idr_lock);
+ xa_erase(&dev_nums, chip->dev_num);
kfree(chip->log.bios_event_log);
kfree(chip->work_space.context_buf);
chip->ops = ops;
- mutex_lock(&idr_lock);
- rc = idr_alloc(&dev_nums_idr, NULL, 0, TPM_NUM_DEVICES, GFP_KERNEL);
- mutex_unlock(&idr_lock);
+ rc = xa_alloc(&dev_nums, &chip->dev_num, NULL,
+ XA_LIMIT(0, TPM_NUM_DEVICES - 1), GFP_KERNEL);
if (rc < 0) {
dev_err(pdev, "No available tpm device numbers\n");
kfree(chip);
return ERR_PTR(rc);
}
- chip->dev_num = rc;
device_initialize(&chip->dev);
device_initialize(&chip->devs);
return chip;
out:
+ kfree(chip->work_space.context_buf);
put_device(&chip->devs);
put_device(&chip->dev);
+ xa_erase(&dev_nums, chip->dev_num);
+ kfree(chip);
return ERR_PTR(rc);
}
EXPORT_SYMBOL_GPL(tpm_chip_alloc);
}
/* Make the chip available. */
- mutex_lock(&idr_lock);
- idr_replace(&dev_nums_idr, chip, chip->dev_num);
- mutex_unlock(&idr_lock);
+ xa_store(&dev_nums, chip->dev_num, chip, GFP_KERNEL);
return rc;
}
cdev_device_del(&chip->cdev, &chip->dev);
/* Make the chip unavailable. */
- mutex_lock(&idr_lock);
- idr_replace(&dev_nums_idr, NULL, chip->dev_num);
- mutex_unlock(&idr_lock);
+ xa_store(&dev_nums, chip->dev_num, NULL, GFP_KERNEL);
/* Make the driver uncallable. */
down_write(&chip->ops_sem);