From: Xianzhong Date: Wed, 25 Apr 2018 19:58:25 +0000 (+0800) Subject: MGS-3848-3 [#imx-854] correct command commit synchronization between pm and other... X-Git-Tag: C0P2-H0.0--20200415~50 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=40a15b534b0551f8026fd85ab9d9dcd7ca7874af;p=linux.git MGS-3848-3 [#imx-854] correct command commit synchronization between pm and other threads When power ON to other mode with broadcast (SUSPEND_BROADCAST, IDLE_BROADCAST, OFF_BROADCAST), command->powerSemaphore is acquired after check idle. code sequence: check commit atom check idle >>> at this point, other thread may have new commits at this >>> point. Acquire command->powerSemaphore ... do clock off This can cause unexpected interrupts after clock OFF or power OFF. To fix: try to acquire powerSemaphore before check commit atom, abort when failure, because command commit is in progress. fix bug #19216, #19230. Signed-off-by: Xianzhong (cherry picked from commit 5228271314e8f575e4bbd9d3087c220b6a344b7d) --- diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c index be8ca1c929a4..e67e2f59f6dc 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c +++ b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c @@ -7863,6 +7863,29 @@ gckHARDWARE_SetPowerManagementState( /* Release the global semaphore again. */ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore)); globalAcquired = gcvFALSE; + + /* Try to acquire the semaphore to make sure commit is not in progress + ** Otherwise, we just abort. */ + if (flag & gcvPOWER_FLAG_ACQUIRE) + { + /* ON -> Other, boardcast. */ + /* Try to acquire the power management semaphore. */ + status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore); + + if (status == gcvSTATUS_OK) + { + acquired = gcvTRUE; + + /* avoid acquiring again. */ + flag &= ~gcvPOWER_FLAG_ACQUIRE; + } + else + { + /* Not ready to swith. */ + status = gcvSTATUS_CHIP_NOT_READY; + goto OnError; + } + } } else {