aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/plat-omap/rproc_user.c62
-rw-r--r--drivers/gpio/gpio-omap.c31
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;
+ }
}
}