diff options
Diffstat (limited to 'arch/arm/plat-omap/rproc_user.c')
-rw-r--r-- | arch/arm/plat-omap/rproc_user.c | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/arch/arm/plat-omap/rproc_user.c b/arch/arm/plat-omap/rproc_user.c index 0764cfe..083e4ae 100644 --- a/arch/arm/plat-omap/rproc_user.c +++ b/arch/arm/plat-omap/rproc_user.c @@ -45,18 +45,27 @@ struct rproc_user_device { static struct rproc_user_device *ipu_device; static char *rproc_user_name = RPROC_USER_NAME; -static bool secure_mode; -static bool secure_attempt; - +static unsigned secure_cnt; static int rproc_user_open(struct inode *inode, struct file *filp) { + filp->private_data = NULL; return 0; } static int rproc_user_release(struct inode *inode, struct file *filp) { - return 0; + int ret = 0; + + if (filp->private_data) { + mutex_lock(&rproc_user_mutex); + if (!--secure_cnt) + ret = rproc_set_secure("ipu", false); + mutex_unlock(&rproc_user_mutex); + if (ret) + pr_err("rproc normal start failed 0x%x, urghh!!", ret); + } + return ret; } static ssize_t rproc_user_read(struct file *filp, char __user *ubuf, @@ -70,7 +79,7 @@ static ssize_t rproc_user_read(struct file *filp, char __user *ubuf, if (mutex_lock_interruptible(&rproc_user_mutex)) return -EINTR; - enable = secure_mode ? 1 : 0; + enable = secure_cnt ? 1 : 0; if (copy_to_user((void *)ubuf, &enable, sizeof(enable))) ret = -EFAULT; mutex_unlock(&rproc_user_mutex); @@ -81,34 +90,45 @@ static ssize_t rproc_user_read(struct file *filp, char __user *ubuf, static ssize_t rproc_user_write(struct file *filp, const char __user *ubuf, size_t len, loff_t *offp) { - int ret; + int ret = 0; u8 enable; if (len != 1) return -EINVAL; - //enable = !(*(u8 *)ubuf == 0); if (copy_from_user(&enable, (char __user *) ubuf, sizeof(enable))) return -EFAULT; - enable = !(enable == 0); if (mutex_lock_interruptible(&rproc_user_mutex)) return -EINTR; - if (enable && !secure_mode) { - ret = rproc_set_secure("ipu", enable); - if (!ret) - secure_mode = enable; - else - pr_err("rproc secure start failed, 0x%x\n", ret); - secure_attempt = enable; - } else if (!enable && secure_attempt) { - ret = rproc_set_secure("ipu", enable); + + enable = enable ? 1 : 0; + if (enable == (int)filp->private_data) { + ret = -EINVAL; + goto out; + } + + switch (enable) { + case 1: + if (!secure_cnt++) + ret = rproc_set_secure("ipu", true); + if (!ret) { + filp->private_data = (void *)1; + goto out; + } + /* fall through in case of failure */ + pr_err("rproc secure start failed, 0x%x\n", ret); + case 0: + if (!--secure_cnt) + ret = rproc_set_secure("ipu", false); if (ret) pr_err("rproc normal start failed 0x%x, urghh!!", ret); - secure_mode = enable; - secure_attempt = enable; - } else - ret = -EINVAL; + else + filp->private_data = (void *)0; + } + if (enable != (int)filp->private_data) + ret = -EACCES; +out: mutex_unlock(&rproc_user_mutex); return ret ? ret : 1; |