summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2011-12-12 13:04:54 +0200
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-15 12:09:05 +0530
commitae4284831e1535446766970dd0fc5a6ae02a3b16 (patch)
tree79642b13c16f059549bd86d7a9e0b0cbbcf7e6cf /drivers
parenta71055465ab8313f2a056603c0bf66110bb183d7 (diff)
video: tegra: host: Prevent suspend if module is busy
MPE is kept artificially busy if a channel is open. This is done to prevent power management during an encoding process. This patch prevents system suspend if any module is busy. Bug 911477 Change-Id: I943a7e29e473ac33e680281fcdce74618567facb Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/69457 Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/dev.c15
-rw-r--r--drivers/video/tegra/host/nvhost_acm.c10
-rw-r--r--drivers/video/tegra/host/nvhost_acm.h2
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c11
-rw-r--r--drivers/video/tegra/host/nvhost_channel.h2
5 files changed, 25 insertions, 15 deletions
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c
index 3af4d3bebfae..75c116b4f081 100644
--- a/drivers/video/tegra/host/dev.c
+++ b/drivers/video/tegra/host/dev.c
@@ -1068,15 +1068,18 @@ static int __exit nvhost_remove(struct platform_device *pdev)
static int nvhost_suspend(struct platform_device *pdev, pm_message_t state)
{
struct nvhost_master *host = platform_get_drvdata(pdev);
- int i;
+ int i, ret;
dev_info(&pdev->dev, "suspending\n");
- for (i = 0; i < host->nb_channels; i++)
- nvhost_channel_suspend(&host->channels[i]);
+ for (i = 0; i < host->nb_channels; i++) {
+ ret = nvhost_channel_suspend(&host->channels[i]);
+ if (ret)
+ return ret;
+ }
- nvhost_module_suspend(&host->mod, true);
- dev_info(&pdev->dev, "suspended\n");
- return 0;
+ ret = nvhost_module_suspend(&host->mod, true);
+ dev_info(&pdev->dev, "suspend status: %d\n", ret);
+ return ret;
}
static int nvhost_resume(struct platform_device *pdev)
diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c
index 6ea1466f63ce..3d63dd62e2fa 100644
--- a/drivers/video/tegra/host/nvhost_acm.c
+++ b/drivers/video/tegra/host/nvhost_acm.c
@@ -450,7 +450,7 @@ static void debug_not_idle(struct nvhost_master *dev)
dev_dbg(&dev->pdev->dev, "tegra_grhost: all locks released\n");
}
-void nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend)
+int nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend)
{
int ret;
struct nvhost_master *dev;
@@ -465,8 +465,10 @@ void nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend)
ret = wait_event_timeout(mod->idle, is_module_idle(mod),
ACM_SUSPEND_WAIT_FOR_IDLE_TIMEOUT);
- if (ret == 0)
- nvhost_debug_dump(dev);
+ if (ret == 0) {
+ dev_info(&dev->pdev->dev, "%s prevented suspend\n", mod->name);
+ return -EBUSY;
+ }
if (system_suspend)
dev_dbg(&dev->pdev->dev, "tegra_grhost: entered idle\n");
@@ -479,7 +481,7 @@ void nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend)
if (mod->desc->suspend)
mod->desc->suspend(mod);
- BUG_ON(nvhost_module_powered(mod));
+ return 0;
}
void nvhost_module_deinit(struct device *dev, struct nvhost_module *mod)
diff --git a/drivers/video/tegra/host/nvhost_acm.h b/drivers/video/tegra/host/nvhost_acm.h
index ce15c9916cd5..1720ff1405fe 100644
--- a/drivers/video/tegra/host/nvhost_acm.h
+++ b/drivers/video/tegra/host/nvhost_acm.h
@@ -85,7 +85,7 @@ int nvhost_module_init(struct nvhost_module *mod, const char *name,
struct nvhost_module *parent,
struct device *dev);
void nvhost_module_deinit(struct device *dev, struct nvhost_module *mod);
-void nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend);
+int nvhost_module_suspend(struct nvhost_module *mod, bool system_suspend);
void nvhost_module_reset(struct device *dev, struct nvhost_module *mod);
void nvhost_module_busy(struct nvhost_module *mod);
diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c
index 3a3b9e2022e9..6c4212d776c7 100644
--- a/drivers/video/tegra/host/nvhost_channel.c
+++ b/drivers/video/tegra/host/nvhost_channel.c
@@ -124,14 +124,19 @@ void nvhost_putchannel(struct nvhost_channel *ch, struct nvhost_hwctx *ctx)
mutex_unlock(&ch->reflock);
}
-void nvhost_channel_suspend(struct nvhost_channel *ch)
+int nvhost_channel_suspend(struct nvhost_channel *ch)
{
+ int ret = 0;
+
mutex_lock(&ch->reflock);
BUG_ON(!channel_cdma_op(ch).stop);
if (ch->refcount) {
- nvhost_module_suspend(&ch->mod, false);
- channel_cdma_op(ch).stop(&ch->cdma);
+ ret = nvhost_module_suspend(&ch->mod, false);
+ if (!ret)
+ channel_cdma_op(ch).stop(&ch->cdma);
}
mutex_unlock(&ch->reflock);
+
+ return ret;
}
diff --git a/drivers/video/tegra/host/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h
index 9158317061c1..f48fff615401 100644
--- a/drivers/video/tegra/host/nvhost_channel.h
+++ b/drivers/video/tegra/host/nvhost_channel.h
@@ -108,7 +108,7 @@ int nvhost_channel_submit(
struct nvhost_channel *nvhost_getchannel(struct nvhost_channel *ch);
void nvhost_putchannel(struct nvhost_channel *ch, struct nvhost_hwctx *ctx);
-void nvhost_channel_suspend(struct nvhost_channel *ch);
+int nvhost_channel_suspend(struct nvhost_channel *ch);
#define channel_cdma_op(ch) (ch->dev->op.cdma)
#define channel_op(ch) (ch->dev->op.channel)