diff options
author | Angela Stegmaier <angelabaker@ti.com> | 2010-09-09 15:32:20 -0500 |
---|---|---|
committer | Ricardo Perez Olivares <x0081762@ti.com> | 2010-09-09 18:22:32 -0500 |
commit | af622912c97a4953e097ca3037fa52ea6d905a30 (patch) | |
tree | 254b6f5c38289e3133189b7b819dd52debce82a6 | |
parent | 2b921ffa3dfd74daf5284021c25f002da2813e3f (diff) |
omap:remoteproc - Add hibernating state
This patch adds a third state called hibernating state. This state
is set when sleep is called to remoteproc. This patch also adds
two new functions called sleep and wakeup.
Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
-rw-r--r-- | arch/arm/mach-omap2/remoteproc44xx.c | 71 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/remoteproc.h | 5 | ||||
-rw-r--r-- | arch/arm/plat-omap/remoteproc.c | 48 |
3 files changed, 117 insertions, 7 deletions
diff --git a/arch/arm/mach-omap2/remoteproc44xx.c b/arch/arm/mach-omap2/remoteproc44xx.c index e752380e531c..b56ea8595465 100644 --- a/arch/arm/mach-omap2/remoteproc44xx.c +++ b/arch/arm/mach-omap2/remoteproc44xx.c @@ -69,18 +69,71 @@ static inline int proc44x_stop(struct device *dev) to_platform_device(dev)); int ret = 0; - ret = omap_device_shutdown(pdev); - if (ret) - dev_err(dev, "%s err 0x%x\n", __func__, ret); + if (obj->state == OMAP_RPROC_RUNNING) { + ret = omap_device_shutdown(pdev); + if (ret) + dev_err(dev, "%s err 0x%x\n", __func__, ret); + + if (!strcmp(obj->name, "tesla")) { + dev_info(dev, "disable GPTIMER5\n"); + cm_write_mod_reg(ABE_GPTIMER_MODULE_DISABLE, + OMAP4430_CM1_ABE_MOD, + OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET); + } + } + + obj->state = OMAP_RPROC_STOPPED; + return ret; +} + +static inline int proc44x_sleep(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata( + to_platform_device(dev)); + int ret = 0; + + if (obj->state == OMAP_RPROC_RUNNING) { + ret = omap_device_shutdown(pdev); + if (ret) + dev_err(dev, "%s err 0x%x\n", __func__, ret); + + if (!strcmp(obj->name, "tesla")) { + dev_info(dev, "disable GPTIMER5\n"); + cm_write_mod_reg(ABE_GPTIMER_MODULE_DISABLE, + OMAP4430_CM1_ABE_MOD, + OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET); + } + } + + obj->state = OMAP_RPROC_HIBERNATING; + return ret; +} + +static inline int proc44x_wakeup(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct omap_rproc *obj = (struct omap_rproc *)platform_get_drvdata( + to_platform_device(dev)); + int ret = 0; if (!strcmp(obj->name, "tesla")) { - dev_info(dev, "disable GPTIMER5\n"); - cm_write_mod_reg(ABE_GPTIMER_MODULE_DISABLE, + dev_info(dev, "Enable GPTIMER5 for Tesla BIOS Clock\n"); + /* Enable the GPTIMER5 clock */ + cm_write_mod_reg(ABE_GPTIMER_MODULE_ENABLE, OMAP4430_CM1_ABE_MOD, OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET); } - obj->state = OMAP_RPROC_STOPPED; + ret = omap_device_enable(pdev); + if (ret) + goto err_start; + + obj->state = OMAP_RPROC_RUNNING; + return 0; + +err_start: + dev_err(dev, "%s error 0x%x\n", __func__, ret); return ret; } @@ -96,18 +149,24 @@ static inline int omap4_rproc_get_state(struct device *dev) static struct omap_rproc_ops omap4_ducati0_ops = { .start = proc44x_start, .stop = proc44x_stop, + .sleep = proc44x_sleep, + .wakeup = proc44x_wakeup, .get_state = omap4_rproc_get_state, }; static struct omap_rproc_ops omap4_ducati1_ops = { .start = proc44x_start, .stop = proc44x_stop, + .sleep = proc44x_sleep, + .wakeup = proc44x_wakeup, .get_state = omap4_rproc_get_state, }; static struct omap_rproc_ops omap4_tesla_ops = { .start = proc44x_start, .stop = proc44x_stop, + .sleep = proc44x_sleep, + .wakeup = proc44x_wakeup, .get_state = omap4_rproc_get_state, }; diff --git a/arch/arm/plat-omap/include/plat/remoteproc.h b/arch/arm/plat-omap/include/plat/remoteproc.h index a49c0ff3c043..1237434af0e6 100644 --- a/arch/arm/plat-omap/include/plat/remoteproc.h +++ b/arch/arm/plat-omap/include/plat/remoteproc.h @@ -41,6 +41,8 @@ struct omap_rproc; struct omap_rproc_ops { int (*start)(struct device *dev, u32 start_addr); int (*stop)(struct device *dev); + int (*sleep)(struct device *dev); + int (*wakeup)(struct device *dev); int (*get_state)(struct device *dev); }; @@ -60,6 +62,7 @@ enum { enum { OMAP_RPROC_STOPPED, OMAP_RPROC_RUNNING, + OMAP_RPROC_HIBERNATING, }; struct omap_rproc_platform_data { @@ -85,6 +88,8 @@ struct omap_rproc_start_args { extern int rproc_start(struct omap_rproc *rproc, const void __user *arg); extern int rproc_stop(struct omap_rproc *rproc); +extern int rproc_sleep(struct omap_rproc *rproc); +extern int rproc_wakeup(struct omap_rproc *rproc); extern int omap_rproc_register_notifier(struct omap_rproc *rproc, struct notifier_block *nb); diff --git a/arch/arm/plat-omap/remoteproc.c b/arch/arm/plat-omap/remoteproc.c index c69e5d023016..f387a71a2edd 100644 --- a/arch/arm/plat-omap/remoteproc.c +++ b/arch/arm/plat-omap/remoteproc.c @@ -102,6 +102,52 @@ int rproc_stop(struct omap_rproc *rproc) } EXPORT_SYMBOL_GPL(rproc_stop); +int rproc_sleep(struct omap_rproc *rproc) +{ + int ret; + struct omap_rproc_platform_data *pdata; + if (!rproc->dev) + return -EINVAL; + + pdata = rproc->dev->platform_data; + if (!pdata->ops) + return -EINVAL; + + ret = mutex_lock_interruptible(&rproc->lock); + if (ret) + return ret; + + ret = pdata->ops->sleep(rproc->dev); + + mutex_unlock(&rproc->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(rproc_sleep); + +int rproc_wakeup(struct omap_rproc *rproc) +{ + int ret; + struct omap_rproc_platform_data *pdata; + + if (!rproc->dev) + return -EINVAL; + + pdata = rproc->dev->platform_data; + if (!pdata->ops) + return -EINVAL; + + ret = mutex_lock_interruptible(&rproc->lock); + if (ret) + return ret; + + ret = pdata->ops->wakeup(rproc->dev); + + mutex_unlock(&rproc->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(rproc_wakeup); static inline int rproc_get_state(struct omap_rproc *rproc) { @@ -172,7 +218,7 @@ static int omap_rproc_release(struct inode *inode, struct file *filp) pdata = rproc->dev->platform_data; count = atomic_dec_return(&rproc->count); - if (!count && (rproc->state == OMAP_RPROC_RUNNING)) + if (!count && (rproc->state != OMAP_RPROC_STOPPED)) rproc_stop(rproc); return 0; |