aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiviu Dudau <Liviu.Dudau@arm.com>2017-05-23 09:18:18 -0400
committerLiviu Dudau <Liviu.Dudau@arm.com>2017-06-16 06:56:46 -0400
commit0df34a807310325cfb910276d631c949aa008d91 (patch)
treed1bc2d585fb4243bc62bf8405435f2e7de50bc73
parente2113c036775408348cf1bd60a5659648220973f (diff)
drm/mali-dp: Check PM status when sharing interrupt lines
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>
-rw-r--r--drivers/gpu/drm/arm/malidp_hw.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 28360b8542f7..17bca99e8ac8 100644
--- 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, void *arg)
766 u32 status, mask, dc_status; 766 u32 status, mask, dc_status;
767 irqreturn_t ret = IRQ_NONE; 767 irqreturn_t ret = IRQ_NONE;
768 768
769 if (!drm->dev_private)
770 return IRQ_HANDLED;
771
772 hwdev = malidp->dev; 769 hwdev = malidp->dev;
773 de = &hwdev->map.de_irq_map; 770 de = &hwdev->map.de_irq_map;
774 771
772 /*
773 * if we are suspended it is likely that we were invoked because
774 * we share an interrupt line with some other driver, don't try
775 * to read the hardware registers
776 */
777 if (hwdev->pm_suspended)
778 return IRQ_NONE;
779
775 /* first handle the config valid IRQ */ 780 /* first handle the config valid IRQ */
776 dc_status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); 781 dc_status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS);
777 if (dc_status & hwdev->map.dc_irq_map.vsync_irq) { 782 if (dc_status & hwdev->map.dc_irq_map.vsync_irq) {
@@ -854,6 +859,14 @@ static irqreturn_t malidp_se_irq(int irq, void *arg)
854 struct malidp_hw_device *hwdev = malidp->dev; 859 struct malidp_hw_device *hwdev = malidp->dev;
855 u32 status, mask; 860 u32 status, mask;
856 861
862 /*
863 * if we are suspended it is likely that we were invoked because
864 * we share an interrupt line with some other driver, don't try
865 * to read the hardware registers
866 */
867 if (hwdev->pm_suspended)
868 return IRQ_NONE;
869
857 status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS); 870 status = malidp_hw_read(hwdev, hwdev->map.se_base + MALIDP_REG_STATUS);
858 if (!(status & hwdev->map.se_irq_map.irq_mask)) 871 if (!(status & hwdev->map.se_irq_map.irq_mask))
859 return IRQ_NONE; 872 return IRQ_NONE;