[FOSS_TLK]security: tlk_driver: add FIQ glue
[tegra/ote_partner/tlk_driver.git] / security / tlk_driver / ote_fs.c
1 /*
2  * Copyright (c) 2013-2014 NVIDIA Corporation. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18
19 #include <linux/slab.h>
20 #include <linux/syscalls.h>
21 #include <linux/list.h>
22 #include <linux/completion.h>
23 #include <linux/workqueue.h>
24 #include <linux/bitops.h>
25 #include <linux/uaccess.h>
26 #include <linux/dma-mapping.h>
27
28 #include "ote_protocol.h"
29
30 static DECLARE_COMPLETION(req_ready);
31 static DECLARE_COMPLETION(req_complete);
32
33 static struct te_ss_op *ss_op_shmem;
34
35 int te_handle_ss_ioctl(struct file *file, unsigned int ioctl_num,
36         unsigned long ioctl_param)
37 {
38         int ss_cmd;
39
40         if (ioctl_num != TE_IOCTL_SS_CMD)
41                 return -EINVAL;
42
43         if (copy_from_user(&ss_cmd, (void __user *)ioctl_param,
44                                 sizeof(ss_cmd))) {
45                 pr_err("%s: copy from user space failed\n", __func__);
46                 return -EFAULT;
47         }
48
49         switch (ss_cmd) {
50         case TE_IOCTL_SS_CMD_GET_NEW_REQ:
51                 /* wait for a new request */
52                 if (wait_for_completion_interruptible(&req_ready))
53                         return -ENODATA;
54                 break;
55         case TE_IOCTL_SS_CMD_REQ_COMPLETE:
56                 /* signal the producer */
57                 complete(&req_complete);
58                 break;
59         default:
60                 pr_err("%s: unknown ss_cmd 0x%x\n", __func__, ss_cmd);
61                 return -EINVAL;
62         }
63
64         return 0;
65 }
66
67 void tlk_ss_op(void)
68 {
69         /* signal consumer */
70         complete(&req_ready);
71
72         /* wait for the consumer's signal */
73         wait_for_completion(&req_complete);
74 }
75
76 static int __init tlk_ss_init(void)
77 {
78         dma_addr_t ss_op_shmem_dma;
79         int32_t ret;
80
81         /* allocate shared memory buffer */
82         ss_op_shmem = dma_alloc_coherent(NULL, sizeof(struct te_ss_op),
83                         &ss_op_shmem_dma, GFP_KERNEL);
84         if (!ss_op_shmem) {
85                 pr_err("%s: no memory available for fs operations\n", __func__);
86                 return -ENOMEM;
87         }
88
89         ret = tlk_generic_smc(TE_SMC_SS_REGISTER_HANDLER,
90                         (uintptr_t)ss_op_shmem, 0);
91         if (ret != 0) {
92                 dma_free_coherent(NULL, sizeof(struct te_ss_op),
93                         (void *)ss_op_shmem, ss_op_shmem_dma);
94                 ss_op_shmem = NULL;
95                 return -ENOTSUPP;
96         }
97
98         return 0;
99 }
100
101 arch_initcall(tlk_ss_init);