Blob Blame History Raw
From: Liviu Dudau <Liviu.Dudau@arm.com>
Date: Tue, 23 May 2017 14:18:18 +0100
Subject: drm/mali-dp: Check PM status when sharing interrupt lines
Git-commit: 0df34a807310325cfb910276d631c949aa008d91
Patch-mainline: v4.13-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

If an instance of Mali DP hardware shares the interrupt line with
another hardware (usually another instance of the Mali DP) its
interrupt handler can get called when the device is suspended.

Check the PM status before making access to the hardware registers
to avoid deadlocks.

Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/arm/malidp_hw.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -766,12 +766,17 @@ static irqreturn_t malidp_de_irq(int irq
 	u32 status, mask, dc_status;
 	irqreturn_t ret = IRQ_NONE;
 
-	if (!drm->dev_private)
-		return IRQ_HANDLED;
-
 	hwdev = malidp->dev;
 	de = &hwdev->map.de_irq_map;
 
+	/*
+	 * if we are suspended it is likely that we were invoked because
+	 * we share an interrupt line with some other driver, don't try
+	 * to read the hardware registers
+	 */
+	if (hwdev->pm_suspended)
+		return IRQ_NONE;
+
 	/* first handle the config valid IRQ */
 	dc_status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS);
 	if (dc_status & hwdev->map.dc_irq_map.vsync_irq) {
@@ -854,6 +859,14 @@ static irqreturn_t malidp_se_irq(int irq
 	struct malidp_hw_device *hwdev = malidp->dev;
 	u32 status, mask;
 
+	/*
+	 * if we are suspended it is likely that we were invoked because
+	 * we share an interrupt line with some other driver, don't try
+	 * to read the hardware registers
+	 */
+	if (hwdev->pm_suspended)
+		return IRQ_NONE;
+
 	status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS);
 	if (!(status & hwdev->map.se_irq_map.irq_mask))
 		return IRQ_NONE;