msm: kgsl: power state cleanup

Clean up kgsl_pwrctrl_sleep() and kgsl_pwrctrl_wake() to make
state transistions clearer.  Add kgsl_pwrctrl_request_state()
and kgsl_pwrctrl_set_state() to make it easier to debug the
state machine.

CRs-Fixed: 315833
Change-Id: I656ce8bd19feabd4186ef91dc031f8a6c6a7d09a
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index d2e4e4b..a8a0e59 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -194,7 +194,7 @@
 
 	if (device->requested_state == KGSL_STATE_NONE) {
 		if (device->pwrctrl.nap_allowed == true) {
-			device->requested_state = KGSL_STATE_NAP;
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 			queue_work(device->work_queue, &device->idle_check_ws);
 		} else if (device->pwrscale.policy != NULL) {
 			queue_work(device->work_queue, &device->idle_check_ws);
@@ -495,8 +495,7 @@
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	int init_reftimestamp = 0x7fffffff;
 
-	device->state = KGSL_STATE_INIT;
-	device->requested_state = KGSL_STATE_NONE;
+	kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
 	/* Power up the device */
 	kgsl_pwrctrl_enable(device);
@@ -716,33 +715,27 @@
 static int
 adreno_dump_and_recover(struct kgsl_device *device)
 {
-	static int recovery;
 	int result = -ETIMEDOUT;
 
 	if (device->state == KGSL_STATE_HUNG)
 		goto done;
-	if (device->state == KGSL_STATE_DUMP_AND_RECOVER && !recovery) {
+	if (device->state == KGSL_STATE_DUMP_AND_RECOVER) {
 		mutex_unlock(&device->mutex);
 		wait_for_completion(&device->recovery_gate);
 		mutex_lock(&device->mutex);
-		if (!(device->state & KGSL_STATE_HUNG))
-			/* recovery success */
+		if (device->state != KGSL_STATE_HUNG)
 			result = 0;
 	} else {
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_DUMP_AND_RECOVER);
 		INIT_COMPLETION(device->recovery_gate);
 		/* Detected a hang - trigger an automatic dump */
 		adreno_postmortem_dump(device, 0);
-		if (!recovery) {
-			recovery = 1;
-			result = adreno_recover_hang(device);
-			if (result)
-				device->state = KGSL_STATE_HUNG;
-			recovery = 0;
-			complete_all(&device->recovery_gate);
-		} else
-			KGSL_DRV_ERR(device,
-				"Cannot recover from another hang while "
-				"recovering from a hang\n");
+		result = adreno_recover_hang(device);
+		if (result)
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
+		else
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+		complete_all(&device->recovery_gate);
 	}
 done:
 	return result;
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 9e49e6a..aafef21 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -21,6 +21,7 @@
 #include "adreno_postmortem.h"
 #include "adreno_debugfs.h"
 #include "kgsl_cffdump.h"
+#include "kgsl_pwrctrl.h"
 
 #include "a2xx_reg.h"
 
@@ -828,11 +829,9 @@
 
 	/* Disable the idle timer so we don't get interrupted */
 	del_timer_sync(&device->idle_timer);
-
 	mutex_unlock(&device->mutex);
 	flush_workqueue(device->work_queue);
 	mutex_lock(&device->mutex);
-	adreno_dump(device);
 
 	/* Turn off napping to make sure we have the clocks full
 	   attention through the following process */
@@ -845,15 +844,7 @@
 	/* Disable the irq */
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 
-	/* If this is not a manual trigger, then set up the
-	   state to try to recover */
-
-	if (!manual) {
-		device->state = KGSL_STATE_DUMP_AND_RECOVER;
-		KGSL_PWR_WARN(device,
-				"state -> DUMP_AND_RECOVER, device %d\n",
-				device->id);
-	}
+	adreno_dump(device);
 
 	/* Restore nap mode */
 	device->pwrctrl.nap_allowed = saved_nap;
@@ -867,7 +858,7 @@
 		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
 
 		/* try to go into a sleep mode until the next event */
-		device->requested_state = KGSL_STATE_SLEEP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
 		kgsl_pwrctrl_sleep(device);
 	}
 
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index a098200..7ace67a 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -393,7 +393,6 @@
 	if (rb->flags & KGSL_FLAGS_STARTED) {
 		/* ME_HALT */
 		adreno_regwrite(rb->device, REG_CP_ME_CNTL, 0x10000000);
-
 		rb->flags &= ~KGSL_FLAGS_STARTED;
 	}
 }
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 7a42dcd..3207040 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -302,7 +302,7 @@
 	if (device->pwrctrl.nap_allowed == true &&
 	    device->state == KGSL_STATE_ACTIVE &&
 		device->requested_state == KGSL_STATE_NONE) {
-		device->requested_state = KGSL_STATE_NAP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 		if (kgsl_pwrctrl_sleep(device) != 0)
 			mod_timer(&device->idle_timer,
 				  jiffies +
@@ -395,7 +395,7 @@
 	device->pwrctrl.nap_allowed = false;
 	policy_saved = device->pwrscale.policy;
 	device->pwrscale.policy = NULL;
-	device->requested_state = KGSL_STATE_SUSPEND;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_SUSPEND);
 	/* Make sure no user process is waiting for a timestamp *
 	 * before supending */
 	if (device->active_cnt != 0) {
@@ -417,22 +417,18 @@
 			INIT_COMPLETION(device->hwaccess_gate);
 			device->ftbl->suspend_context(device);
 			device->ftbl->stop(device);
-			device->state = KGSL_STATE_SUSPEND;
-			KGSL_PWR_WARN(device, "state -> SUSPEND, device %d\n",
-				device->id);
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_SUSPEND);
 			break;
 		case KGSL_STATE_SLUMBER:
 			INIT_COMPLETION(device->hwaccess_gate);
-			device->state = KGSL_STATE_SUSPEND;
-			KGSL_PWR_WARN(device, "state -> SUSPEND, device %d\n",
-				device->id);
+			kgsl_pwrctrl_set_state(device, KGSL_STATE_SUSPEND);
 			break;
 		default:
 			KGSL_PWR_ERR(device, "suspend fail, device %d\n",
 					device->id);
 			goto end;
 	}
-	device->requested_state = KGSL_STATE_NONE;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 	device->pwrctrl.nap_allowed = nap_allowed_saved;
 	device->pwrscale.policy = policy_saved;
 	status = 0;
@@ -453,14 +449,11 @@
 	KGSL_PWR_WARN(device, "resume start\n");
 	mutex_lock(&device->mutex);
 	if (device->state == KGSL_STATE_SUSPEND) {
-		device->state = KGSL_STATE_SLUMBER;
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
 		status = 0;
-		KGSL_PWR_WARN(device,
-				"state -> SLUMBER, device %d\n",
-				device->id);
 		complete_all(&device->hwaccess_gate);
 	}
-	device->requested_state = KGSL_STATE_NONE;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 
 	mutex_unlock(&device->mutex);
 	KGSL_PWR_WARN(device, "resume end\n");
@@ -505,7 +498,7 @@
 					struct kgsl_device, display_off);
 	KGSL_PWR_WARN(device, "early suspend start\n");
 	mutex_lock(&device->mutex);
-	device->requested_state = KGSL_STATE_SLUMBER;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_SLUMBER);
 	kgsl_pwrctrl_sleep(device);
 	mutex_unlock(&device->mutex);
 	KGSL_PWR_WARN(device, "early suspend end\n");
@@ -535,6 +528,7 @@
 	mutex_lock(&device->mutex);
 	kgsl_pwrctrl_wake(device);
 	device->pwrctrl.restore_slumber = 0;
+	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
 	mutex_unlock(&device->mutex);
 	kgsl_check_idle(device);
 	KGSL_PWR_WARN(device, "late resume end\n");
@@ -651,8 +645,7 @@
 	device->open_count--;
 	if (device->open_count == 0) {
 		result = device->ftbl->stop(device);
-		device->state = KGSL_STATE_INIT;
-		KGSL_PWR_WARN(device, "state -> INIT, device %d\n", device->id);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 	}
 	/* clean up any to-be-freed entries that belong to this
 	 * process and this device
@@ -720,9 +713,7 @@
 			mutex_unlock(&device->mutex);
 			goto err_putprocess;
 		}
-		device->state = KGSL_STATE_ACTIVE;
-		KGSL_PWR_WARN(device,
-				"state -> ACTIVE, device %d\n", minor);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
 	}
 	device->open_count++;
 	mutex_unlock(&device->mutex);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index dbbe4d5..89b4df1 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -599,6 +599,9 @@
 {
 	struct kgsl_device *device = container_of(work, struct kgsl_device,
 							idle_check_ws);
+	WARN_ON(device == NULL);
+	if (device == NULL)
+		return;
 
 	mutex_lock(&device->mutex);
 	if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
@@ -620,7 +623,7 @@
 		}
 	} else if (device->state & (KGSL_STATE_HUNG |
 					KGSL_STATE_DUMP_AND_RECOVER)) {
-		device->requested_state = KGSL_STATE_NONE;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 	}
 
 	mutex_unlock(&device->mutex);
@@ -632,7 +635,7 @@
 
 	KGSL_PWR_INFO(device, "idle timer expired device %d\n", device->id);
 	if (device->requested_state != KGSL_STATE_SUSPEND) {
-		device->requested_state = KGSL_STATE_SLEEP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
 		/* Have work run in a non-interrupt context. */
 		queue_work(device->work_queue, &device->idle_check_ws);
 	}
@@ -663,155 +666,182 @@
 }
 
 static int
-_slumber(struct kgsl_device *device)
+_nap(struct kgsl_device *device)
 {
-	int status = -EINVAL;
-	if (!device)
-		return -EINVAL;
-	KGSL_PWR_WARN(device, "Slumber start\n");
-
-	device->requested_state = KGSL_STATE_SLUMBER;
-	del_timer(&device->idle_timer);
 	switch (device->state) {
 	case KGSL_STATE_ACTIVE:
-		/* Wait for the device to become idle */
-		device->ftbl->idle(device, KGSL_TIMEOUT_DEFAULT);
+		if (!device->ftbl->isidle(device)) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			return -EBUSY;
+		}
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP);
+		if (device->idle_wakelock.name)
+			wake_unlock(&device->idle_wakelock);
 	case KGSL_STATE_NAP:
 	case KGSL_STATE_SLEEP:
-		device->ftbl->suspend_context(device);
-		device->ftbl->stop(device);
-		device->state = KGSL_STATE_SLUMBER;
-		device->pwrctrl.restore_slumber = 1;
-		KGSL_PWR_WARN(device, "state -> SLUMBER, device %d\n",
-				device->id);
+	case KGSL_STATE_SLUMBER:
 		break;
 	default:
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
 		break;
 	}
-	status = 0;
-	/* Don't set requested state to NONE
-	It's done in kgsl_pwrctrl_sleep*/
-	KGSL_PWR_WARN(device, "Done going to slumber\n");
-	return status;
+	return 0;
+}
+
+static void
+_sleep_accounting(struct kgsl_device *device)
+{
+	kgsl_pwrctrl_busy_time(device, false);
+	device->pwrctrl.busy.start.tv_sec = 0;
+	device->pwrctrl.time = 0;
+	kgsl_pwrscale_sleep(device);
+}
+
+static int
+_sleep(struct kgsl_device *device)
+{
+	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	switch (device->state) {
+	case KGSL_STATE_ACTIVE:
+		if (!device->ftbl->isidle(device)) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			return -EBUSY;
+		}
+		/* fall through */
+	case KGSL_STATE_NAP:
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
+		if (pwr->pwrlevels[0].gpu_freq > 0)
+			clk_set_rate(pwr->grp_clks[0],
+				pwr->pwrlevels[pwr->num_pwrlevels - 1].
+				gpu_freq);
+		_sleep_accounting(device);
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLEEP);
+		if (device->idle_wakelock.name)
+			wake_unlock(&device->idle_wakelock);
+		break;
+	case KGSL_STATE_SLEEP:
+	case KGSL_STATE_SLUMBER:
+		break;
+	default:
+		KGSL_PWR_WARN(device, "unhandled state %x\n",
+				device->state);
+		break;
+	}
+	return 0;
+}
+
+static int
+_slumber(struct kgsl_device *device)
+{
+	switch (device->state) {
+	case KGSL_STATE_ACTIVE:
+		if (!device->ftbl->isidle(device)) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			device->pwrctrl.restore_slumber = true;
+			return -EBUSY;
+		}
+		/* fall through */
+	case KGSL_STATE_NAP:
+	case KGSL_STATE_SLEEP:
+		del_timer_sync(&device->idle_timer);
+		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+		device->ftbl->suspend_context(device);
+		device->ftbl->stop(device);
+		device->pwrctrl.restore_slumber = true;
+		_sleep_accounting(device);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
+		if (device->idle_wakelock.name)
+			wake_unlock(&device->idle_wakelock);
+		break;
+	case KGSL_STATE_SLUMBER:
+		break;
+	default:
+		KGSL_PWR_WARN(device, "unhandled state %x\n",
+				device->state);
+		break;
+	}
+	return 0;
 }
 
 /******************************************************************/
 /* Caller must hold the device mutex. */
 int kgsl_pwrctrl_sleep(struct kgsl_device *device)
 {
-	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+	int status = 0;
 	KGSL_PWR_INFO(device, "sleep device %d\n", device->id);
 
 	/* Work through the legal state transitions */
-	if ((device->requested_state == KGSL_STATE_NAP)) {
+	switch (device->requested_state) {
+	case KGSL_STATE_NAP:
 		if (device->pwrctrl.restore_slumber) {
-			device->requested_state = KGSL_STATE_NONE;
-			return 0;
-		} else if (device->ftbl->isidle(device))
-			goto nap;
-	} else if (device->requested_state == KGSL_STATE_SLEEP) {
-		if (device->state == KGSL_STATE_NAP ||
-			device->ftbl->isidle(device)) {
-			if (!device->pwrctrl.restore_slumber)
-				goto sleep;
-			else
-				goto slumber;
-			}
-	} else if (device->requested_state == KGSL_STATE_SLUMBER) {
-		if (device->state == KGSL_STATE_INIT)
-			return 0;
-		if (device->ftbl->isidle(device))
-			goto slumber;
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			break;
+		}
+		status = _nap(device);
+		break;
+	case KGSL_STATE_SLEEP:
+		if (device->pwrctrl.restore_slumber)
+			status = _slumber(device);
 		else
-			device->pwrctrl.restore_slumber = true;
+			status = _sleep(device);
+		break;
+	case KGSL_STATE_SLUMBER:
+		status = _slumber(device);
+		break;
+	default:
+		KGSL_PWR_INFO(device, "bad state request 0x%x\n",
+				device->requested_state);
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+		status = -EINVAL;
+		break;
 	}
-
-	device->requested_state = KGSL_STATE_NONE;
-	return -EBUSY;
-
-
-slumber:
-	_slumber(device);
-
-sleep:
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
-	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
-	if (pwr->pwrlevels[0].gpu_freq > 0)
-		clk_set_rate(pwr->grp_clks[0],
-				pwr->pwrlevels[pwr->num_pwrlevels - 1].
-				gpu_freq);
-	kgsl_pwrctrl_busy_time(device, false);
-	pwr->busy.start.tv_sec = 0;
-	device->pwrctrl.time = 0;
-
-	kgsl_pwrscale_sleep(device);
-	goto clk_off;
-
-nap:
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
-clk_off:
-	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF);
-
-	device->state = device->requested_state;
-	device->requested_state = KGSL_STATE_NONE;
-	if (device->idle_wakelock.name)
-		wake_unlock(&device->idle_wakelock);
-	KGSL_PWR_WARN(device, "state -> NAP/SLEEP(%d), device %d\n",
-				  device->state, device->id);
-
-	return 0;
-}
-EXPORT_SYMBOL(kgsl_pwrctrl_sleep);
-
-static int
-_wake_from_slumber(struct kgsl_device *device)
-{
-	int status = -EINVAL;
-	if (!device)
-		return -EINVAL;
-
-	KGSL_PWR_WARN(device, "wake from slumber start\n");
-
-	device->requested_state = KGSL_STATE_ACTIVE;
-	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
-	status = device->ftbl->start(device, 0);
-	device->requested_state = KGSL_STATE_NONE;
-
-	KGSL_PWR_WARN(device, "Done waking from slumber\n");
 	return status;
 }
+EXPORT_SYMBOL(kgsl_pwrctrl_sleep);
 
 /******************************************************************/
 /* Caller must hold the device mutex. */
 void kgsl_pwrctrl_wake(struct kgsl_device *device)
 {
-	if (device->state & (KGSL_STATE_SUSPEND | KGSL_STATE_INIT))
-		return;
-
-	if (device->state == KGSL_STATE_SLUMBER)
-		_wake_from_slumber(device);
-
-	if (device->state != KGSL_STATE_NAP) {
+	int status;
+	kgsl_pwrctrl_request_state(device, KGSL_STATE_ACTIVE);
+	switch (device->state) {
+	case KGSL_STATE_SLUMBER:
+		status = device->ftbl->start(device, 0);
+		if (status) {
+			kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+			KGSL_DRV_ERR(device, "start failed %d\n", status);
+			break;
+		}
+		/* fall through */
+	case KGSL_STATE_SLEEP:
 		kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);
 		kgsl_pwrscale_wake(device);
-	}
-
-	/* Turn on the core clocks */
-	kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON);
-
-	/* Enable state before turning on irq */
-	device->state = KGSL_STATE_ACTIVE;
-	KGSL_PWR_WARN(device, "state -> ACTIVE, device %d\n", device->id);
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
-
-	/* Re-enable HW access */
-	mod_timer(&device->idle_timer,
+		/* fall through */
+	case KGSL_STATE_NAP:
+		/* Turn on the core clocks */
+		kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON);
+		/* Enable state before turning on irq */
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_ACTIVE);
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
+		/* Re-enable HW access */
+		mod_timer(&device->idle_timer,
 				jiffies + device->pwrctrl.interval_timeout);
 
-	if (device->idle_wakelock.name)
-		wake_lock(&device->idle_wakelock);
-
-	KGSL_PWR_INFO(device, "wake return for device %d\n", device->id);
+		if (device->idle_wakelock.name)
+			wake_lock(&device->idle_wakelock);
+	case KGSL_STATE_ACTIVE:
+		break;
+	default:
+		KGSL_PWR_WARN(device, "unhandled state %x\n",
+				device->state);
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE);
+		break;
+	}
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_wake);
 
@@ -832,3 +862,19 @@
 	kgsl_pwrctrl_pwrrail(device, KGSL_PWRFLAGS_OFF);
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_disable);
+
+void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state)
+{
+	KGSL_PWR_WARN(device, "%x\n", state);
+	device->state = state;
+	device->requested_state = KGSL_STATE_NONE;
+}
+EXPORT_SYMBOL(kgsl_pwrctrl_set_state);
+
+void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state)
+{
+	if (state != KGSL_STATE_NONE && state != device->requested_state)
+		KGSL_PWR_INFO(device, "%x\n", state);
+	device->requested_state = state;
+}
+EXPORT_SYMBOL(kgsl_pwrctrl_request_state);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 8b33fcd..8ec41be 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -77,4 +77,6 @@
 	return (clk != NULL) ? clk_get_rate(clk) : 0;
 }
 
+void kgsl_pwrctrl_set_state(struct kgsl_device *device, unsigned int state);
+void kgsl_pwrctrl_request_state(struct kgsl_device *device, unsigned int state);
 #endif /* __KGSL_PWRCTRL_H */
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index c64d6ff..de7d1be 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -248,7 +248,7 @@
 
 	if ((device->pwrctrl.nap_allowed == true) &&
 		(device->requested_state == KGSL_STATE_NONE)) {
-		device->requested_state = KGSL_STATE_NAP;
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_NAP);
 		queue_work(device->work_queue, &device->idle_check_ws);
 	}
 	mod_timer(&device->idle_timer,
@@ -553,9 +553,7 @@
 {
 	int status = 0;
 
-	device->state = KGSL_STATE_INIT;
-	device->requested_state = KGSL_STATE_NONE;
-	KGSL_PWR_WARN(device, "state -> INIT, device %d\n", device->id);
+	kgsl_pwrctrl_set_state(device, KGSL_STATE_INIT);
 
 	kgsl_pwrctrl_enable(device);
 
@@ -836,8 +834,7 @@
 		status = 0;
 	else if (timeout == 0) {
 		status = -ETIMEDOUT;
-		device->state = KGSL_STATE_HUNG;
-		KGSL_PWR_WARN(device, "state -> HUNG, device %d\n", device->id);
+		kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
 	} else
 		status = timeout;