diff options
author | Terje Bergstrom <tbergstrom@nvidia.com> | 2011-12-12 13:04:54 +0200 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-15 12:09:05 +0530 |
commit | ae4284831e1535446766970dd0fc5a6ae02a3b16 (patch) | |
tree | 79642b13c16f059549bd86d7a9e0b0cbbcf7e6cf /drivers/video/tegra/host | |
parent | a71055465ab8313f2a056603c0bf66110bb183d7 (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/video/tegra/host')
-rw-r--r-- | drivers/video/tegra/host/dev.c | 15 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_acm.c | 10 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_acm.h | 2 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.c | 11 | ||||
-rw-r--r-- | drivers/video/tegra/host/nvhost_channel.h | 2 |
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) |