summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2012-08-22 09:16:51 +0300
committerLokesh Pathak <lpathak@nvidia.com>2012-08-29 07:23:54 -0700
commit63644abd0d4ed41c5f6894e273a41968ea09694e (patch)
treed19df646761165e03a3c63374c0d5089bf083d96 /drivers
parent9c153df4f3b2ef23622ae3c1807f1e207cefd49b (diff)
video: tegra: host: Disable irq when clock gating
Disable host1x interrupts when clock gating host1x. This fixes a race where host1x interrupt was raised at the same time when host1x clock is turned off. Bug 1031724 Change-Id: I169cd5796608b8888a6b48ed99bb5da754559b2c Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/125129 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra/host/host1x/host1x.c15
-rw-r--r--drivers/video/tegra/host/nvhost_acm.c19
2 files changed, 33 insertions, 1 deletions
diff --git a/drivers/video/tegra/host/host1x/host1x.c b/drivers/video/tegra/host/host1x/host1x.c
index 33ebc1ff5d22..31899c78065b 100644
--- a/drivers/video/tegra/host/host1x/host1x.c
+++ b/drivers/video/tegra/host/host1x/host1x.c
@@ -308,6 +308,19 @@ static int power_off_host(struct nvhost_device *dev)
return 0;
}
+static void clock_on_host(struct nvhost_device *dev)
+{
+ struct nvhost_master *host = nvhost_get_drvdata(dev);
+ nvhost_intr_start(&host->intr, clk_get_rate(dev->clk[0]));
+}
+
+static int clock_off_host(struct nvhost_device *dev)
+{
+ struct nvhost_master *host = nvhost_get_drvdata(dev);
+ nvhost_intr_stop(&host->intr);
+ return 0;
+}
+
static int __devinit nvhost_user_init(struct nvhost_master *host)
{
int err, devno;
@@ -516,6 +529,8 @@ static struct nvhost_driver nvhost_driver = {
},
.finalize_poweron = power_on_host,
.prepare_poweroff = power_off_host,
+ .finalize_clockon = clock_on_host,
+ .prepare_clockoff = clock_off_host,
};
static int __init nvhost_mod_init(void)
diff --git a/drivers/video/tegra/host/nvhost_acm.c b/drivers/video/tegra/host/nvhost_acm.c
index 76304d6e8fa6..5bde55ad2ff5 100644
--- a/drivers/video/tegra/host/nvhost_acm.c
+++ b/drivers/video/tegra/host/nvhost_acm.c
@@ -101,8 +101,17 @@ void nvhost_module_reset(struct nvhost_device *dev)
static void to_state_clockgated_locked(struct nvhost_device *dev)
{
+ struct nvhost_driver *drv = to_nvhost_driver(dev->dev.driver);
+
if (dev->powerstate == NVHOST_POWER_STATE_RUNNING) {
- int i;
+ int i, err;
+ if (drv->prepare_clockoff) {
+ err = drv->prepare_clockoff(dev);
+ if (err) {
+ dev_err(&dev->dev, "error clock gating");
+ return;
+ }
+ }
for (i = 0; i < dev->num_clks; i++)
clk_disable(dev->clk[i]);
if (dev->dev.parent)
@@ -141,6 +150,14 @@ static void to_state_running_locked(struct nvhost_device *dev)
}
}
+ /* Invoke callback after enabling clock. This is used for
+ * re-enabling host1x interrupts. */
+ if (prev_state == NVHOST_POWER_STATE_CLOCKGATED
+ && drv->finalize_clockon)
+ drv->finalize_clockon(dev);
+
+ /* Invoke callback after power un-gating. This is used for
+ * restoring context. */
if (prev_state == NVHOST_POWER_STATE_POWERGATED
&& drv->finalize_poweron)
drv->finalize_poweron(dev);