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_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 1649391..c29da39 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -362,6 +362,7 @@
 		}
 	}
 }
+EXPORT_SYMBOL(kgsl_pwrctrl_clk);
 
 void kgsl_pwrctrl_axi(struct kgsl_device *device, int state)
 {
@@ -849,6 +850,16 @@
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_disable);
 
+void kgsl_pwrctrl_stop_work(struct kgsl_device *device)
+{
+	del_timer_sync(&device->idle_timer);
+	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+	mutex_unlock(&device->mutex);
+	flush_workqueue(device->work_queue);
+	mutex_lock(&device->mutex);
+}
+EXPORT_SYMBOL(kgsl_pwrctrl_stop_work);
+
 void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state)
 {
 	trace_kgsl_pwr_set_state(device, state);