aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/remoteproc
diff options
context:
space:
mode:
authorLuden <luden@ghostmail.com>2016-01-30 01:07:26 +0100
committerZiyan <jaraidaniel@gmail.com>2016-05-01 23:35:54 +0200
commit0ff6b8dd50f90858213cca674a1865b2b6c7391f (patch)
tree530eb344e15c1102e9750d91f6d6f4d69d27d85c /drivers/remoteproc
parent980a74e2c46a5f8b8ae8ef4e73dbcc4bf26443b9 (diff)
downloadkernel_samsung_tuna-0ff6b8dd50f90858213cca674a1865b2b6c7391f.tar.gz
kernel_samsung_tuna-0ff6b8dd50f90858213cca674a1865b2b6c7391f.tar.bz2
kernel_samsung_tuna-0ff6b8dd50f90858213cca674a1865b2b6c7391f.zip
OMAP: switch Ducati allocations to CMA
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r--drivers/remoteproc/omap_remoteproc.c21
-rwxr-xr-xdrivers/remoteproc/remoteproc.c84
2 files changed, 89 insertions, 16 deletions
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c
index 7c10c79501e..cc62ef61ebc 100644
--- a/drivers/remoteproc/omap_remoteproc.c
+++ b/drivers/remoteproc/omap_remoteproc.c
@@ -479,6 +479,9 @@ static inline int omap_rproc_start(struct rproc *rproc, u64 bootaddr)
}
ret = omap_device_enable(pdev);
+ if (ret) {
+ dev_err(rproc->dev, "failed to enable device: %d\n", ret);
+ }
out:
if (ret) {
while (i--) {
@@ -507,10 +510,16 @@ static int omap_rproc_iommu_exit(struct rproc *rproc)
return 0;
}
+static inline struct omap_device *_find_by_pdev(struct platform_device *pdev)
+{
+ return container_of(pdev, struct omap_device, pdev);
+}
+
static inline int omap_rproc_stop(struct rproc *rproc)
{
struct device *dev = rproc->dev;
struct platform_device *pdev = to_platform_device(dev);
+ struct omap_device *od = _find_by_pdev(pdev);
struct omap_rproc_pdata *pdata = dev->platform_data;
struct omap_rproc_timers_info *timers = pdata->timers;
int ret, i;
@@ -526,9 +535,15 @@ static inline int omap_rproc_stop(struct rproc *rproc)
rproc->secure_reset = false;
}
- ret = omap_device_idle(pdev);
- if (ret)
- goto err;
+ /* We might be called from the suspended state,
+ * in that case we shouldn't try to call omap_device_idle(). */
+ if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
+ ret = omap_device_idle(pdev);
+ if (ret)
+ goto err;
+ } else {
+ ret = 0;
+ }
for (i = 0; i < pdata->timers_cnt; i++) {
#ifdef CONFIG_REMOTEPROC_WATCHDOG
diff --git a/drivers/remoteproc/remoteproc.c b/drivers/remoteproc/remoteproc.c
index 65d2c79ce06..939274c434e 100755
--- a/drivers/remoteproc/remoteproc.c
+++ b/drivers/remoteproc/remoteproc.c
@@ -35,11 +35,14 @@
#include <linux/list.h>
#include <linux/debugfs.h>
#include <linux/remoteproc.h>
+#include <linux/rpmsg.h>
#include <linux/pm_runtime.h>
#include <linux/uaccess.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <plat/remoteproc.h>
+#include <linux/ion.h>
+#include <linux/omap_ion.h>
/* list of available remote processors on this board */
static LIST_HEAD(rprocs);
@@ -1261,7 +1264,7 @@ int rproc_error_notify(struct rproc *rproc)
}
EXPORT_SYMBOL_GPL(rproc_error_notify);
-struct rproc *rproc_get(const char *name)
+static struct rproc *_rproc_get(const char *name, bool use_refcounting)
{
struct rproc *rproc, *ret = NULL;
struct device *dev;
@@ -1297,7 +1300,13 @@ struct rproc *rproc_get(const char *name)
}
/* bail if rproc is already powered up */
- if (rproc->count++) {
+ if (use_refcounting && rproc->count++) {
+ ret = rproc;
+ goto unlock_mutex;
+ }
+
+ if (use_refcounting && rproc->state != RPROC_OFFLINE) {
+ dev_info(dev, "redundant rproc restart request, ignoring\n");
ret = rproc;
goto unlock_mutex;
}
@@ -1305,6 +1314,13 @@ struct rproc *rproc_get(const char *name)
/* rproc_put() calls should wait until async loader completes */
init_completion(&rproc->firmware_loading_complete);
+#ifdef CONFIG_CMA
+ if (!omap_ion_ipu_allocate_memory()) {
+ ret = NULL;
+ goto unlock_mutex;
+ }
+#endif
+
dev_info(dev, "powering up %s\n", name);
err = rproc_loader(rproc);
@@ -1312,7 +1328,7 @@ struct rproc *rproc_get(const char *name)
dev_err(dev, "failed to load rproc %s\n", rproc->name);
complete_all(&rproc->firmware_loading_complete);
module_put(rproc->owner);
- --rproc->count;
+ rproc->count -= (use_refcounting ? 1 : 0);
goto unlock_mutex;
}
@@ -1323,9 +1339,14 @@ unlock_mutex:
mutex_unlock(&rproc->lock);
return ret;
}
+
+struct rproc *rproc_get(const char *name)
+{
+ return _rproc_get(name, true);
+}
EXPORT_SYMBOL_GPL(rproc_get);
-void rproc_put(struct rproc *rproc)
+static void _rproc_put(struct rproc *rproc, bool use_refcounting)
{
struct device *dev = rproc->dev;
int ret;
@@ -1339,14 +1360,14 @@ void rproc_put(struct rproc *rproc)
return;
}
- if (!rproc->count) {
+ if (use_refcounting && !rproc->count) {
dev_warn(dev, "asymmetric rproc_put\n");
ret = -EINVAL;
goto out;
}
/* if the remote proc is still needed, bail out */
- if (--rproc->count)
+ if (use_refcounting && --rproc->count)
goto out;
if (mutex_lock_interruptible(&rproc->tlock))
@@ -1380,13 +1401,15 @@ void rproc_put(struct rproc *rproc)
*/
if (rproc->state != RPROC_OFFLINE && rproc->state != RPROC_LOADING) {
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
- /*
- * Call resume, it will cancel any pending autosuspend,
- * so that no callback is executed after the device is stopped.
- * Device stop function takes care of shutting down the device.
- */
- pm_runtime_get_sync(rproc->dev);
- pm_runtime_put_noidle(rproc->dev);
+ if (use_refcounting) {
+ /*
+ * Call resume, it will cancel any pending autosuspend,
+ * so that no callback is executed after the device is stopped.
+ * Device stop function takes care of shutting down the device.
+ */
+ pm_runtime_get_sync(rproc->dev);
+ pm_runtime_put_noidle(rproc->dev);
+ }
if (!rproc->secure_reset)
pm_runtime_disable(rproc->dev);
@@ -1423,11 +1446,19 @@ void rproc_put(struct rproc *rproc)
dev_info(dev, "stopped remote processor %s\n", rproc->name);
+#ifdef CONFIG_CMA
+ omap_ion_ipu_free_memory();
+#endif
+
out:
mutex_unlock(&rproc->lock);
if (!ret)
module_put(rproc->owner);
}
+void rproc_put(struct rproc *rproc)
+{
+ return _rproc_put(rproc, true);
+}
EXPORT_SYMBOL_GPL(rproc_put);
static void rproc_error_work(struct work_struct *work)
@@ -1450,6 +1481,8 @@ int rproc_event_unregister(struct rproc *rproc, struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(rproc_event_unregister);
+static int rproc_runtime_resume(struct device *dev);
+
void rproc_last_busy(struct rproc *rproc)
{
#ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND
@@ -1471,6 +1504,11 @@ void rproc_last_busy(struct rproc *rproc)
mutex_unlock(&rproc->lock);
return;
}
+ if (rproc->state == RPROC_OFFLINE) {
+ mutex_unlock(&rproc->lock);
+ rproc_runtime_resume(dev);
+ return;
+ }
mutex_unlock(&rproc->lock);
pm_runtime_get_sync(dev);
pm_runtime_mark_last_busy(dev);
@@ -1556,6 +1594,12 @@ out:
return ret;
}
+static void rproc_unload_work(struct work_struct *work)
+{
+ struct rproc *rproc = container_of(work, struct rproc, unload_work);
+ _rproc_put(rproc, false);
+}
+
static int rproc_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1564,6 +1608,12 @@ static int rproc_runtime_resume(struct device *dev)
dev_dbg(dev, "Enter %s\n", __func__);
+ if (rproc->state == RPROC_OFFLINE) {
+ dev_info(dev, "rproc_runtime_resume in RPROC_OFFLINE mode - waking up.\n");
+ _rproc_get(rproc->name, false);
+ rpmsg_reset_all_devices();
+ }
+
if (rproc->ops->resume)
ret = rproc->ops->resume(rproc);
@@ -1628,6 +1678,11 @@ static int rproc_runtime_suspend(struct device *dev)
_event_notify(rproc, RPROC_POS_SUSPEND, NULL);
mutex_unlock(&rproc->pm_lock);
+#ifdef CONFIG_CMA
+ /* Unload firmware and free memory */
+ schedule_work(&rproc->unload_work);
+#endif
+
return 0;
abort:
pm_runtime_mark_last_busy(dev);
@@ -1721,6 +1776,9 @@ int rproc_register(struct device *dev, const char *name,
mutex_init(&rproc->secure_lock);
mutex_init(&rproc->tlock);
INIT_WORK(&rproc->error_work, rproc_error_work);
+#ifdef CONFIG_CMA
+ INIT_WORK(&rproc->unload_work, rproc_unload_work);
+#endif
BLOCKING_INIT_NOTIFIER_HEAD(&rproc->nbh);
rproc->state = RPROC_OFFLINE;