GNU Linux-libre 4.14.313-gnu1
[releases.git] / drivers / char / tpm / tpm-dev.c
1 /*
2  * Copyright (C) 2004 IBM Corporation
3  * Authors:
4  * Leendert van Doorn <leendert@watson.ibm.com>
5  * Dave Safford <safford@watson.ibm.com>
6  * Reiner Sailer <sailer@watson.ibm.com>
7  * Kylene Hall <kjhall@us.ibm.com>
8  *
9  * Copyright (C) 2013 Obsidian Research Corp
10  * Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
11  *
12  * Device file system interface to the TPM
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License as
16  * published by the Free Software Foundation, version 2 of the
17  * License.
18  *
19  */
20 #include <linux/slab.h>
21 #include "tpm-dev.h"
22
23 static int tpm_open(struct inode *inode, struct file *file)
24 {
25         struct tpm_chip *chip;
26         struct file_priv *priv;
27
28         chip = container_of(inode->i_cdev, struct tpm_chip, cdev);
29
30         /* It's assured that the chip will be opened just once,
31          * by the check of is_open variable, which is protected
32          * by driver_lock. */
33         if (test_and_set_bit(0, &chip->is_open)) {
34                 dev_dbg(&chip->dev, "Another process owns this TPM\n");
35                 return -EBUSY;
36         }
37
38         priv = kzalloc(sizeof(*priv), GFP_KERNEL);
39         if (priv == NULL)
40                 goto out;
41
42         tpm_common_open(file, chip, priv);
43
44         return 0;
45
46  out:
47         clear_bit(0, &chip->is_open);
48         return -ENOMEM;
49 }
50
51 static ssize_t tpm_write(struct file *file, const char __user *buf,
52                          size_t size, loff_t *off)
53 {
54         return tpm_common_write(file, buf, size, off, NULL);
55 }
56
57 /*
58  * Called on file close
59  */
60 static int tpm_release(struct inode *inode, struct file *file)
61 {
62         struct file_priv *priv = file->private_data;
63
64         tpm_common_release(file, priv);
65         clear_bit(0, &priv->chip->is_open);
66         kfree(priv);
67
68         return 0;
69 }
70
71 const struct file_operations tpm_fops = {
72         .owner = THIS_MODULE,
73         .llseek = no_llseek,
74         .open = tpm_open,
75         .read = tpm_common_read,
76         .write = tpm_write,
77         .release = tpm_release,
78 };