summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPaul Hunt <hunt@ti.com>2012-07-19 13:22:23 -0500
committerAndy Green <andy.green@linaro.org>2012-09-07 13:06:44 +0800
commit93ce91e676f41a1f597ab7edd7f535e9efeb675d (patch)
tree33ecf45e514de8aaf8caee133a7273d98073a160 /drivers
parent5799d7a0d761fd21ef3a45dcb1a0ab0ce542db81 (diff)
remoteproc: control iommu power transitions
The iommu, being part of the remoteproc, needs to be controlled by the remoteproc for sleep transitions too. The associated iommu can be put to a lower power state for sleep transitions that happen for the remoteproc. Helper functions that call the idle and activate functions on the iommu domain have been implemented, and called appropriated in the regular and runtime suspend and resume functions of a remoteproc. Signed-off-by: Paul Hunt <hunt@ti.com> Signed-off-by: Fernando Guzman Lugo <fernando.lugo@ti.com> Signed-off-by: Omar Ramirez Luna <omar.ramirez@ti.com> Signed-off-by: Subramaniam Chanderashekarapuram <subramaniam.ca@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/remoteproc/remoteproc_core.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index f52c9013d0cc..44d3fe6fcec7 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -83,6 +83,24 @@ static const char * const rproc_err_names[] = {
[RPROC_ERR_WATCHDOG] = "watchdog fired",
};
+static void rproc_activate_iommu(struct rproc *rproc)
+{
+ struct iommu_domain *domain = rproc->domain;
+
+ dev_dbg(&rproc->dev, "activating iommu\n");
+ if (domain)
+ iommu_domain_activate(domain);
+}
+
+static void rproc_idle_iommu(struct rproc *rproc)
+{
+ struct iommu_domain *domain = rproc->domain;
+
+ dev_dbg(&rproc->dev, "de-activating iommu\n");
+ if (domain)
+ iommu_domain_idle(domain);
+}
+
static int rproc_resume(struct device *dev)
{
struct rproc *rproc = dev_to_rproc(dev);
@@ -114,12 +132,15 @@ static int rproc_resume(struct device *dev)
/*
* if a system suspend request came when rproc was running, the
* rproc was forced to go to suspend by the system suspend callback.
- * However, the rproc runtime status is still active. In this
- * case we only need to wake up the rproc and update rproc state
+ * However, the rproc runtime status is still active. In this case,
+ * we only need to wake up the rproc, its associated iommu and update
+ * the rproc state
*/
+ rproc_activate_iommu(rproc);
if (rproc->ops->resume) {
ret = rproc->ops->resume(rproc);
if (ret) {
+ rproc_idle_iommu(rproc);
dev_err(dev, "resume failed %d\n", ret);
goto out;
}
@@ -152,6 +173,7 @@ static int rproc_suspend(struct device *dev)
goto out;
}
}
+ rproc_idle_iommu(rproc);
/*
* rproc was not already suspended, so we forced the suspend and
@@ -186,9 +208,11 @@ static int rproc_runtime_resume(struct device *dev)
return -EAGAIN;
}
+ rproc_activate_iommu(rproc);
if (rproc->ops->resume) {
ret = rproc->ops->resume(rproc);
if (ret) {
+ rproc_idle_iommu(rproc);
dev_err(dev, "resume failed %d\n", ret);
goto out;
}
@@ -214,6 +238,7 @@ static int rproc_runtime_suspend(struct device *dev)
if (ret)
goto abort;
}
+ rproc_idle_iommu(rproc);
rproc->state = RPROC_SUSPENDED;
out: