msm: kgsl: flush device workqueue before stop
Make sure the irq is off, the idle timer is
stopped and the workqueue is flushed before
stopping the device for early suspend, suspend,
last release or hang recovery. There is one case
where the workqueue cannot be flushed, which is from
kgsl_pwrctrl_sleep() when going into SLUMBER
state. This codepath can be called from the
workqueue itself so flushing would deadlock.
Change-Id: I19bcd192845401ac0d94aa60a9252970b634c1ea
Signed-off-by: Tarun Karra <tkarra@codeaurora.org>
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 3207040..e9c3f08 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -403,8 +403,6 @@
wait_for_completion(&device->suspend_gate);
mutex_lock(&device->mutex);
}
- /* Don't let the timer wake us during suspended sleep. */
- del_timer_sync(&device->idle_timer);
switch (device->state) {
case KGSL_STATE_INIT:
break;
@@ -416,6 +414,7 @@
/* Get the completion ready to be waited upon. */
INIT_COMPLETION(device->hwaccess_gate);
device->ftbl->suspend_context(device);
+ kgsl_pwrctrl_stop_work(device);
device->ftbl->stop(device);
kgsl_pwrctrl_set_state(device, KGSL_STATE_SUSPEND);
break;
@@ -499,6 +498,7 @@
KGSL_PWR_WARN(device, "early suspend start\n");
mutex_lock(&device->mutex);
kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
+ kgsl_pwrctrl_stop_work(device);
kgsl_pwrctrl_sleep(device);
mutex_unlock(&device->mutex);
KGSL_PWR_WARN(device, "early suspend end\n");
@@ -644,6 +644,7 @@
device->open_count--;
if (device->open_count == 0) {
+ kgsl_pwrctrl_stop_work(device);
result = device->ftbl->stop(device);
kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
}