summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index dcf4daf5bae4..bc316b3c0acb 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -1597,6 +1597,8 @@ gckOS_ReadRegisterEx(
{
if (in_irq())
{
+ uint32_t data;
+
spin_lock(&Os->registerAccessLock);
if (unlikely(Os->clockStates[Core] == gcvFALSE))
@@ -1604,12 +1606,29 @@ gckOS_ReadRegisterEx(
spin_unlock(&Os->registerAccessLock);
/*
- * Read register when power off:
+ * Read register when external clock off:
* 1. In shared IRQ, read register may be called and that's not our irq.
*/
return gcvSTATUS_GENERIC_IO;
}
+ data = readl(Os->device->registerBases[Core]);
+
+ if (unlikely((data & 0x3) == 0x3))
+ {
+ spin_unlock(&Os->registerAccessLock);
+
+ /*
+ * Read register when internal clock off:
+ * a. In shared IRQ, read register may be called and that's not our irq.
+ * b. In some condition, when ISR handled normal FE/PE, PM thread could
+ * trun off internal clock before ISR read register of async FE. And
+ * then IRQ handler will call read register with internal clock off.
+ * So here we just skip for such case.
+ */
+ return gcvSTATUS_GENERIC_IO;
+ }
+
*Data = readl((gctUINT8 *)Os->device->registerBases[Core] + Address);
spin_unlock(&Os->registerAccessLock);
}
@@ -1624,7 +1643,7 @@ gckOS_ReadRegisterEx(
spin_unlock_irqrestore(&Os->registerAccessLock, flags);
/*
- * Read register when power off:
+ * Read register when external clock off:
* 2. In non-irq context, register access should not be called,
* otherwise it's driver bug.
*/