From 77f0fde9a36abaad114bdf5d9b79e4f9416f7896 Mon Sep 17 00:00:00 2001 From: Deepak Kumar Date: Mon, 19 Sep 2016 20:33:22 +0530 Subject: msm: kgsl: Reschedule idle work in case transition to idle state fails Reschedule the idle work in case transition to idle state is rejected because the GPU is busy. This change avoids the condition where transition to NAP state gets rejected due to a pending IRQ which is currently getting served by IRQ handler because of which GPU remains in active state even when GPU is idle. Change-Id: I472a30b6a0e83cdd6957ed12eaa39d0c7731fcb5 Signed-off-by: Deepak Kumar --- drivers/gpu/msm/kgsl_pwrctrl.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c index 1f2178848664..0fcc0c3b0d49 100644 --- a/drivers/gpu/msm/kgsl_pwrctrl.c +++ b/drivers/gpu/msm/kgsl_pwrctrl.c @@ -1913,20 +1913,38 @@ void kgsl_idle_check(struct work_struct *work) { struct kgsl_device *device = container_of(work, struct kgsl_device, idle_check_ws); + int ret = 0; + unsigned int requested_state; + WARN_ON(device == NULL); if (device == NULL) return; mutex_lock(&device->mutex); + requested_state = device->requested_state; + if (device->state == KGSL_STATE_ACTIVE || device->state == KGSL_STATE_NAP) { - if (!atomic_read(&device->active_cnt)) - kgsl_pwrctrl_change_state(device, + if (!atomic_read(&device->active_cnt)) { + ret = kgsl_pwrctrl_change_state(device, device->requested_state); + if (ret == -EBUSY) { + /* + * If the GPU is currently busy, restore + * the requested state and reschedule + * idle work. + */ + kgsl_pwrctrl_request_state(device, + requested_state); + kgsl_schedule_work(&device->idle_check_ws); + } + } + + if (!ret) + kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); - kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); if (device->state == KGSL_STATE_ACTIVE) mod_timer(&device->idle_timer, jiffies + -- cgit v1.2.3