diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
index 5427748..8a7d56ec 100644
--- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -300,9 +300,12 @@ static int a3xx_hw_init(struct msm_gpu *gpu)
 static void a3xx_recover(struct msm_gpu *gpu)
 {
 	struct drm_printer p = drm_info_printer(gpu->dev->dev);
+	struct msm_gpu_state *state;
 	int i;
 
-	adreno_show_info(gpu, &p);
+	state = gpu->funcs->gpu_state_get(gpu);
+
+	adreno_show_info(gpu, state, &p);
 
 	for (i = 0; i < 8; i++)
 		drm_printf(&p, "CP_SCRATCH_REG%d: %u\n", i,
@@ -310,12 +313,14 @@ static void a3xx_recover(struct msm_gpu *gpu)
 
 	/* dump registers before resetting gpu, if enabled: */
 	if (hang_debug)
-		adreno_show_regs(gpu, &p);
+		adreno_show_regs(gpu, state, &p);
 
 	gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 1);
 	gpu_read(gpu, REG_A3XX_RBBM_SW_RESET_CMD);
 	gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 0);
 	adreno_recover(gpu);
+
+	gpu->funcs->gpu_state_put(state);
 }
 
 static void a3xx_destroy(struct msm_gpu *gpu)
@@ -409,15 +414,6 @@ static irqreturn_t a3xx_irq(struct msm_gpu *gpu)
 	~0   /* sentinel */
 };
 
-#ifdef CONFIG_DEBUG_FS
-static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m)
-{
-	seq_printf(m, "status:   %08x\n",
-			gpu_read(gpu, REG_A3XX_RBBM_STATUS));
-	adreno_show(gpu, m);
-}
-#endif
-
 static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu)
 {
 	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
@@ -454,7 +450,7 @@ static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu)
 		.irq = a3xx_irq,
 		.destroy = a3xx_destroy,
 #ifdef CONFIG_DEBUG_FS
-		.show = a3xx_show,
+		.show = adreno_show,
 #endif
 		.gpu_state_get = a3xx_gpu_state_get,
 		.gpu_state_put = adreno_gpu_state_put,
diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
index 4c66c54..e64c7fc 100644
--- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c
@@ -298,9 +298,12 @@ static int a4xx_hw_init(struct msm_gpu *gpu)
 static void a4xx_recover(struct msm_gpu *gpu)
 {
 	struct drm_printer p = drm_info_printer(gpu->dev->dev);
+	struct msm_gpu_state *state;
 	int i;
 
-	adreno_show_info(gpu, &p);
+	state = gpu->funcs->gpu_state_get(gpu);
+
+	adreno_show_info(gpu, state, &p);
 
 	for (i = 0; i < 8; i++) {
 		drm_printf(&p, "CP_SCRATCH_REG%d: %u\n", i,
@@ -309,12 +312,14 @@ static void a4xx_recover(struct msm_gpu *gpu)
 
 	/* dump registers before resetting gpu, if enabled: */
 	if (hang_debug)
-		adreno_show_regs(gpu, &p);
+		adreno_show_regs(gpu, state, &p);
 
 	gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 1);
 	gpu_read(gpu, REG_A4XX_RBBM_SW_RESET_CMD);
 	gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 0);
 	adreno_recover(gpu);
+
+	gpu->funcs->gpu_state_put(state);
 }
 
 static void a4xx_destroy(struct msm_gpu *gpu)
@@ -454,16 +459,6 @@ static irqreturn_t a4xx_irq(struct msm_gpu *gpu)
 	~0 /* sentinel */
 };
 
-#ifdef CONFIG_DEBUG_FS
-static void a4xx_show(struct msm_gpu *gpu, struct seq_file *m)
-{
-	seq_printf(m, "status:   %08x\n",
-			gpu_read(gpu, REG_A4XX_RBBM_STATUS));
-	adreno_show(gpu, m);
-
-}
-#endif
-
 static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
 {
 	struct msm_gpu_state *state = adreno_gpu_state_get(gpu);
@@ -543,7 +538,7 @@ static int a4xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
 		.irq = a4xx_irq,
 		.destroy = a4xx_destroy,
 #ifdef CONFIG_DEBUG_FS
-		.show = a4xx_show,
+		.show = adreno_show,
 #endif
 		.gpu_state_get = a4xx_gpu_state_get,
 		.gpu_state_put = adreno_gpu_state_put,
diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index 05046e4..6747b7b 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -755,21 +755,26 @@ static int a5xx_hw_init(struct msm_gpu *gpu)
 static void a5xx_recover(struct msm_gpu *gpu)
 {
 	struct drm_printer p = drm_info_printer(gpu->dev->dev);
+	struct msm_gpu_state *state;
 	int i;
 
-	adreno_show_info(gpu, &p);
+	state = gpu->funcs->gpu_state_get(gpu);
+
+	adreno_show_info(gpu, state, &p);
 
 	for (i = 0; i < 8; i++)
 		drm_printf(&p, "CP_SCRATCH_REG%d: %u\n", i,
 			gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(i)));
 
 	if (hang_debug)
-		adreno_show_regs(gpu, &p);
+		adreno_show_regs(gpu, state, &p);
 
 	gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 1);
 	gpu_read(gpu, REG_A5XX_RBBM_SW_RESET_CMD);
 	gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 0);
 	adreno_recover(gpu);
+
+	gpu->funcs->gpu_state_put(state);
 }
 
 static void a5xx_destroy(struct msm_gpu *gpu)
@@ -1153,22 +1158,6 @@ static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
 	return state;
 }
 
-#ifdef CONFIG_DEBUG_FS
-static void a5xx_show(struct msm_gpu *gpu, struct seq_file *m)
-{
-	seq_printf(m, "status:   %08x\n",
-			gpu_read(gpu, REG_A5XX_RBBM_STATUS));
-
-	/*
-	 * Temporarily disable hardware clock gating before going into
-	 * adreno_show to avoid issues while reading the registers
-	 */
-	a5xx_set_hwcg(gpu, false);
-	adreno_show(gpu, m);
-	a5xx_set_hwcg(gpu, true);
-}
-#endif
-
 static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -1190,7 +1179,7 @@ static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)
 		.irq = a5xx_irq,
 		.destroy = a5xx_destroy,
 #ifdef CONFIG_DEBUG_FS
-		.show = a5xx_show,
+		.show = adreno_show,
 #endif
 		.gpu_state_get = a5xx_gpu_state_get,
 		.gpu_state_put = adreno_gpu_state_put,
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 64da461..ba1b912 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -416,54 +416,54 @@ void adreno_gpu_state_put(struct msm_gpu_state *state)
 	kfree(state);
 }
 
-void adreno_show_info(struct msm_gpu *gpu, struct drm_printer *p)
+void adreno_show_info(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	int i;
 
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	drm_printf(p, "status:   %08x\n", state->rbbm_status);
 	drm_printf(p, "revision: %d (%d.%d.%d.%d)\n",
 			adreno_gpu->info->revn, adreno_gpu->rev.core,
 			adreno_gpu->rev.major, adreno_gpu->rev.minor,
 			adreno_gpu->rev.patchid);
 
 	for (i = 0; i < gpu->nr_rings; i++) {
-		struct msm_ringbuffer *ring = gpu->rb[i];
-
 		drm_printf(p, "rb %d: fence:    %d/%d\n", i,
-			ring->memptrs->fence, ring->seqno);
+			state->ring[i].fence, state->ring[i].seqno);
 
-		drm_printf(p, "      rptr:     %d\n",
-			get_rptr(adreno_gpu, ring));
-		drm_printf(p, "rb wptr:  %d\n", get_wptr(ring));
+		drm_printf(p, "      rptr:     %d\n", state->ring[i].rptr);
+		drm_printf(p, "rb wptr:  %d\n", state->ring[i].wptr);
 	}
 }
 
-void adreno_show_regs(struct msm_gpu *gpu, struct drm_printer *p)
+void adreno_show_regs(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p)
 {
-	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
 	int i;
 
+	if (IS_ERR_OR_NULL(state))
+		return;
+
 	/* dump these out in a form that can be parsed by demsm: */
 	drm_printf(p, "IO:region %s 00000000 00020000\n", gpu->name);
-	for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
-		uint32_t start = adreno_gpu->registers[i];
-		uint32_t end   = adreno_gpu->registers[i+1];
-		uint32_t addr;
-
-		for (addr = start; addr <= end; addr++) {
-			uint32_t val = gpu_read(gpu, addr);
-			drm_printf(p, "IO:R %08x %08x\n", addr<<2, val);
-		}
-	}
+	for (i = 0; i < state->nr_registers; i++)
+		drm_printf(p, "IO:R %08x %08x\n",
+			state->registers[i * 2] << 2,
+			state->registers[(i * 2) + 1]);
 }
 
 #ifdef CONFIG_DEBUG_FS
-void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
+void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct seq_file *m)
 {
 	struct drm_printer p = drm_seq_file_printer(m);
 
-	adreno_show_info(gpu, &p);
-	adreno_show_regs(gpu, &p);
+	adreno_show_info(gpu, state, &p);
+	adreno_show_regs(gpu, state, &p);
 }
 #endif
 
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
index b7c95ee..4542b6b 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -211,7 +211,8 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
 void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
 #ifdef CONFIG_DEBUG_FS
-void adreno_show(struct msm_gpu *gpu, struct seq_file *m);
+void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct seq_file *m);
 #endif
 void adreno_dump_info(struct msm_gpu *gpu);
 void adreno_dump(struct msm_gpu *gpu);
@@ -223,8 +224,10 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
 		int nr_rings);
 void adreno_gpu_cleanup(struct adreno_gpu *gpu);
 
-void adreno_show_info(struct msm_gpu *gpu, struct drm_printer *p);
-void adreno_show_regs(struct msm_gpu *gpu, struct drm_printer *p);
+void adreno_show_info(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p);
+void adreno_show_regs(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p);
 
 struct msm_gpu_state *adreno_gpu_state_get(struct msm_gpu *gpu);
 void adreno_gpu_state_put(struct msm_gpu_state *state);
diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c
index 1855182..89ee74b 100644
--- a/drivers/gpu/drm/msm/msm_debugfs.c
+++ b/drivers/gpu/drm/msm/msm_debugfs.c
@@ -25,13 +25,22 @@ static int msm_gpu_show(struct drm_device *dev, struct seq_file *m)
 {
 	struct msm_drm_private *priv = dev->dev_private;
 	struct msm_gpu *gpu = priv->gpu;
+	struct msm_gpu_state *state;
 
-	if (gpu) {
-		seq_printf(m, "%s Status:\n", gpu->name);
-		pm_runtime_get_sync(&gpu->pdev->dev);
-		gpu->funcs->show(gpu, m);
-		pm_runtime_put_sync(&gpu->pdev->dev);
-	}
+	if (!gpu)
+		return 0;
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	state = gpu->funcs->gpu_state_get(gpu);
+	pm_runtime_put_sync(&gpu->pdev->dev);
+
+	if (IS_ERR(state))
+		return PTR_ERR(state);
+
+	seq_printf(m, "%s Status:\n", gpu->name);
+	gpu->funcs->show(gpu, state, m);
+
+	gpu->funcs->gpu_state_put(state);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index d781489..cff52ca 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -65,7 +65,8 @@ struct msm_gpu_funcs {
 	void (*destroy)(struct msm_gpu *gpu);
 #ifdef CONFIG_DEBUG_FS
 	/* show GPU status in debugfs: */
-	void (*show)(struct msm_gpu *gpu, struct seq_file *m);
+	void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
+			struct seq_file *m);
 #endif
 	struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
 	void (*gpu_state_put)(struct msm_gpu_state *state);
