ARM: cpu topology: Add debugfs interface for cpu_power
[cmplus.git] / arch / arm / plat-omap / rproc_user.c
blob083e4ae1136e2f231b5c31f830f3e8f6820258d9
1 /*
2 * Secure Mode Input interface to remoteproc driver
4 * Copyright (C) 2011 Texas Instruments. All rights reserved.
6 * Authors: Suman Anna <s-anna@ti.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/device.h>
26 #include <linux/miscdevice.h>
27 #include <linux/cdev.h>
28 #include <linux/uaccess.h>
29 #include <linux/file.h>
30 #include <linux/poll.h>
31 #include <linux/err.h>
32 #include <linux/slab.h>
34 #include <linux/remoteproc.h>
37 #define RPROC_USER_NAME "rproc_user"
38 #define RPROC_USER_DEVICES 1
40 static DEFINE_MUTEX(rproc_user_mutex);
42 struct rproc_user_device {
43 struct miscdevice mdev;
46 static struct rproc_user_device *ipu_device;
47 static char *rproc_user_name = RPROC_USER_NAME;
48 static unsigned secure_cnt;
50 static int rproc_user_open(struct inode *inode, struct file *filp)
52 filp->private_data = NULL;
53 return 0;
56 static int rproc_user_release(struct inode *inode, struct file *filp)
58 int ret = 0;
60 if (filp->private_data) {
61 mutex_lock(&rproc_user_mutex);
62 if (!--secure_cnt)
63 ret = rproc_set_secure("ipu", false);
64 mutex_unlock(&rproc_user_mutex);
65 if (ret)
66 pr_err("rproc normal start failed 0x%x, urghh!!", ret);
68 return ret;
71 static ssize_t rproc_user_read(struct file *filp, char __user *ubuf,
72 size_t len, loff_t *offp)
74 u8 enable;
75 int ret = 1;
77 if (len != 1)
78 return -EINVAL;
80 if (mutex_lock_interruptible(&rproc_user_mutex))
81 return -EINTR;
82 enable = secure_cnt ? 1 : 0;
83 if (copy_to_user((void *)ubuf, &enable, sizeof(enable)))
84 ret = -EFAULT;
85 mutex_unlock(&rproc_user_mutex);
87 return ret;
90 static ssize_t rproc_user_write(struct file *filp, const char __user *ubuf,
91 size_t len, loff_t *offp)
93 int ret = 0;
94 u8 enable;
96 if (len != 1)
97 return -EINVAL;
99 if (copy_from_user(&enable, (char __user *) ubuf, sizeof(enable)))
100 return -EFAULT;
102 if (mutex_lock_interruptible(&rproc_user_mutex))
103 return -EINTR;
105 enable = enable ? 1 : 0;
106 if (enable == (int)filp->private_data) {
107 ret = -EINVAL;
108 goto out;
111 switch (enable) {
112 case 1:
113 if (!secure_cnt++)
114 ret = rproc_set_secure("ipu", true);
115 if (!ret) {
116 filp->private_data = (void *)1;
117 goto out;
119 /* fall through in case of failure */
120 pr_err("rproc secure start failed, 0x%x\n", ret);
121 case 0:
122 if (!--secure_cnt)
123 ret = rproc_set_secure("ipu", false);
124 if (ret)
125 pr_err("rproc normal start failed 0x%x, urghh!!", ret);
126 else
127 filp->private_data = (void *)0;
129 if (enable != (int)filp->private_data)
130 ret = -EACCES;
131 out:
132 mutex_unlock(&rproc_user_mutex);
134 return ret ? ret : 1;
137 static const struct file_operations rproc_user_fops = {
138 .owner = THIS_MODULE,
139 .open = rproc_user_open,
140 .release = rproc_user_release,
141 .read = rproc_user_read,
142 .write = rproc_user_write,
145 static int __init rproc_user_init(void)
147 int ret;
149 ipu_device = kzalloc(sizeof(struct rproc_user_device), GFP_KERNEL);
150 if (!ipu_device) {
151 pr_err("%s: memory allocation failed for ipu_device\n",
152 __func__);
153 ret = -ENOMEM;
154 goto exit;
157 ipu_device->mdev.minor = MISC_DYNAMIC_MINOR;
158 ipu_device->mdev.name = rproc_user_name;
159 ipu_device->mdev.fops = &rproc_user_fops;
160 ipu_device->mdev.parent = NULL;
161 ret = misc_register(&ipu_device->mdev);
162 if (ret) {
163 pr_err("rproc_user_init: failed to register rproc_user misc "
164 "device\n");
165 goto misc_fail;
167 return ret;
169 misc_fail:
170 kfree(ipu_device);
171 exit:
172 return ret;
174 module_init(rproc_user_init);
176 static void __exit rproc_user_exit(void)
178 misc_deregister(&ipu_device->mdev);
179 kfree(ipu_device);
181 module_exit(rproc_user_exit);
183 MODULE_LICENSE("GPL v2");
184 MODULE_DESCRIPTION("RemoteProc Secure Mode Interface Driver");
185 MODULE_AUTHOR("Suman Anna");