diff options
-rw-r--r-- | arch/arm/plat-omap/rproc_user.c | 62 | ||||
-rw-r--r-- | drivers/gpio/gpio-omap.c | 31 |
2 files changed, 68 insertions, 25 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; diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 26231e2..71f4628 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1394,6 +1394,12 @@ void omap2_gpio_set_edge_wakeup(void) u32 level_high = 0; u32 wkup_status = 0; + if (IS_ERR_VALUE(pm_runtime_get_sync(bank->dev) < 0)) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync " + "failed\n", __func__, bank->id); + return; + } + level_low = __raw_readl(bank->base + bank->regs->leveldetect0); level_high = __raw_readl(bank->base + @@ -1411,10 +1417,15 @@ void omap2_gpio_set_edge_wakeup(void) * even if they are set for level detection only. */ __raw_writel(bank->context.edge_falling | (level_low & wkup_status), - (bank->base + bank->regs->fallingdetect)); + (bank->base + bank->regs->fallingdetect)); __raw_writel(bank->context.edge_rising | (level_high & wkup_status), - (bank->base + bank->regs->risingdetect)); + (bank->base + bank->regs->risingdetect)); + if (IS_ERR_VALUE(pm_runtime_put_sync_suspend(bank->dev) < 0)) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync " + "failed\n", __func__, bank->id); + return; + } } } @@ -1424,10 +1435,22 @@ void omap2_gpio_restore_edge_wakeup(void) list_for_each_entry(bank, &omap_gpio_list, node) { /* restore edge setting */ + if (IS_ERR_VALUE(pm_runtime_get_sync(bank->dev) < 0)) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_get_sync " + "failed\n", __func__, bank->id); + return; + } + __raw_writel(bank->context.edge_falling, - (bank->base + bank->regs->fallingdetect)); + (bank->base + bank->regs->fallingdetect)); __raw_writel(bank->context.edge_rising, - (bank->base + bank->regs->risingdetect)); + (bank->base + bank->regs->risingdetect)); + + if (IS_ERR_VALUE(pm_runtime_put_sync_suspend(bank->dev) < 0)) { + dev_err(bank->dev, "%s: GPIO bank %d pm_runtime_put_sync " + "failed\n", __func__, bank->id); + return; + } } } |