diff options
Diffstat (limited to 'drivers/char/tpm/tpm-dev.c')
-rw-r--r-- | drivers/char/tpm/tpm-dev.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c new file mode 100644 index 000000000..ebd74ab5a --- /dev/null +++ b/drivers/char/tpm/tpm-dev.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2004 IBM Corporation + * Authors: + * Leendert van Doorn <leendert@watson.ibm.com> + * Dave Safford <safford@watson.ibm.com> + * Reiner Sailer <sailer@watson.ibm.com> + * Kylene Hall <kjhall@us.ibm.com> + * + * Copyright (C) 2013 Obsidian Research Corp + * Jason Gunthorpe <jgunthorpe@obsidianresearch.com> + * + * Device file system interface to the TPM + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + */ +#include <linux/slab.h> +#include "tpm-dev.h" + +static int tpm_open(struct inode *inode, struct file *file) +{ + struct tpm_chip *chip; + struct file_priv *priv; + + chip = container_of(inode->i_cdev, struct tpm_chip, cdev); + + /* It's assured that the chip will be opened just once, + * by the check of is_open variable, which is protected + * by driver_lock. */ + if (test_and_set_bit(0, &chip->is_open)) { + dev_dbg(&chip->dev, "Another process owns this TPM\n"); + return -EBUSY; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (priv == NULL) + goto out; + + tpm_common_open(file, chip, priv); + + return 0; + + out: + clear_bit(0, &chip->is_open); + return -ENOMEM; +} + +static ssize_t tpm_write(struct file *file, const char __user *buf, + size_t size, loff_t *off) +{ + return tpm_common_write(file, buf, size, off, NULL); +} + +/* + * Called on file close + */ +static int tpm_release(struct inode *inode, struct file *file) +{ + struct file_priv *priv = file->private_data; + + tpm_common_release(file, priv); + clear_bit(0, &priv->chip->is_open); + kfree(priv); + + return 0; +} + +const struct file_operations tpm_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = tpm_open, + .read = tpm_common_read, + .write = tpm_write, + .release = tpm_release, +}; |