瀏覽代碼

drm/msm/dpu: merge dpu_hw_intr_get_interrupt_statuses into dpu_hw_intr_dispatch_irqs

There is little sense in reading interrupt statuses and right after that
going after the array of statuses to dispatch them. Merge both loops
into single function doing read and dispatch.

Change-Id: I1259476549bcaf9f9f4e12591a7e182796e150dd
Signed-off-by: Dmitry Baryshkov <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
Git-commit: 0abdba47dc1df708c365421d481734d3f7fecb01
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Signed-off-by: Veera Sundaram Sankaran <[email protected]>
Dmitry Baryshkov 2 年之前
父節點
當前提交
5ddbc95058
共有 3 個文件被更改,包括 22 次插入64 次删除
  1. 1 9
      msm/sde/sde_core_irq.c
  2. 20 46
      msm/sde/sde_hw_interrupts.c
  3. 1 9
      msm/sde/sde_hw_interrupts.h

+ 1 - 9
msm/sde/sde_core_irq.c

@@ -616,15 +616,6 @@ int sde_core_irq_domain_fini(struct sde_kms *sde_kms)
 
 irqreturn_t sde_core_irq(struct sde_kms *sde_kms)
 {
-	/*
-	 * Read interrupt status from all sources. Interrupt status are
-	 * stored within hw_intr.
-	 * Function will also clear the interrupt status after reading.
-	 * Individual interrupt status bit will only get stored if it
-	 * is enabled.
-	 */
-	sde_kms->hw_intr->ops.get_interrupt_statuses(sde_kms->hw_intr);
-
 	/*
 	 * Dispatch to HW driver to handle interrupt lookup that is being
 	 * fired. When matching interrupt is located, HW driver will call to
@@ -632,6 +623,7 @@ irqreturn_t sde_core_irq(struct sde_kms *sde_kms)
 	 * sde_core_irq_callback_handler will perform the registered function
 	 * callback, and do the interrupt status clearing once the registered
 	 * callback is finished.
+	 * Function will also clear the interrupt status after reading.
 	 */
 	sde_kms->hw_intr->ops.dispatch_irqs(
 			sde_kms->hw_intr,

+ 20 - 46
msm/sde/sde_hw_interrupts.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -415,6 +415,7 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
 	int start_idx;
 	int end_idx;
 	u32 irq_status;
+	u32 enable_mask;
 	unsigned long irq_flags;
 
 	if (!intr)
@@ -427,8 +428,6 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
 	 */
 	spin_lock_irqsave(&intr->irq_lock, irq_flags);
 	for (reg_idx = 0; reg_idx < intr->sde_irq_size; reg_idx++) {
-		irq_status = intr->save_irq_status[reg_idx];
-
 		/*
 		 * Each Interrupt register has dynamic range of indexes,
 		 * initialized during hw_intr_init when sde_irq_tbl is created.
@@ -440,6 +439,20 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
 				end_idx > intr->sde_irq_map_size)
 			continue;
 
+		/* Read interrupt status */
+		irq_status = SDE_REG_READ(&intr->hw, intr->sde_irq_tbl[reg_idx].status_off);
+
+		/* Read enable mask */
+		enable_mask = SDE_REG_READ(&intr->hw, intr->sde_irq_tbl[reg_idx].en_off);
+
+		/* and clear the interrupt */
+		if (irq_status)
+			SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[reg_idx].clr_off,
+					irq_status);
+
+		/* Finally update IRQ status based on enable mask */
+		irq_status &= enable_mask;
+
 		/*
 		 * Search through matching intr status from irq map.
 		 * start_idx and end_idx defined the search range in
@@ -474,6 +487,10 @@ static void sde_hw_intr_dispatch_irq(struct sde_hw_intr *intr,
 					~intr->sde_irq_map[irq_idx].irq_mask;
 			}
 	}
+
+	/* ensure register writes go through */
+	wmb();
+
 	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
 }
 
@@ -620,40 +637,6 @@ static int sde_hw_intr_get_interrupt_sources(struct sde_hw_intr *intr,
 	return 0;
 }
 
-static void sde_hw_intr_get_interrupt_statuses(struct sde_hw_intr *intr)
-{
-	int i;
-	u32 enable_mask;
-	unsigned long irq_flags;
-
-	if (!intr)
-		return;
-
-	spin_lock_irqsave(&intr->irq_lock, irq_flags);
-	for (i = 0; i < intr->sde_irq_size; i++) {
-		/* Read interrupt status */
-		intr->save_irq_status[i] = SDE_REG_READ(&intr->hw,
-				intr->sde_irq_tbl[i].status_off);
-
-		/* Read enable mask */
-		enable_mask = SDE_REG_READ(&intr->hw,
-				intr->sde_irq_tbl[i].en_off);
-
-		/* and clear the interrupt */
-		if (intr->save_irq_status[i])
-			SDE_REG_WRITE(&intr->hw, intr->sde_irq_tbl[i].clr_off,
-					intr->save_irq_status[i]);
-
-		/* Finally update IRQ status based on enable mask */
-		intr->save_irq_status[i] &= enable_mask;
-	}
-
-	/* ensure register writes go through */
-	wmb();
-
-	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
-}
-
 static void sde_hw_intr_clear_intr_status_nolock(struct sde_hw_intr *intr,
 		int irq_idx)
 {
@@ -856,7 +839,6 @@ static void __setup_intr_ops(struct sde_hw_intr_ops *ops)
 	ops->clear_all_irqs = sde_hw_intr_clear_irqs;
 	ops->disable_all_irqs = sde_hw_intr_disable_irqs;
 	ops->get_interrupt_sources = sde_hw_intr_get_interrupt_sources;
-	ops->get_interrupt_statuses = sde_hw_intr_get_interrupt_statuses;
 	ops->clear_interrupt_status = sde_hw_intr_clear_interrupt_status;
 	ops->clear_intr_status_nolock = sde_hw_intr_clear_intr_status_nolock;
 	ops->get_interrupt_status = sde_hw_intr_get_interrupt_status;
@@ -881,7 +863,6 @@ void sde_hw_intr_destroy(struct sde_hw_intr *intr)
 		kfree(intr->sde_irq_tbl);
 		kfree(intr->sde_irq_map);
 		kfree(intr->cache_irq_mask);
-		kfree(intr->save_irq_status);
 		kfree(intr);
 	}
 }
@@ -1151,13 +1132,6 @@ struct sde_hw_intr *sde_hw_intr_init(void __iomem *addr,
 		goto exit;
 	}
 
-	intr->save_irq_status = kcalloc(intr->sde_irq_size,
-			sizeof(*intr->save_irq_status), GFP_KERNEL);
-	if (intr->save_irq_status == NULL) {
-		ret = -ENOMEM;
-		goto exit;
-	}
-
 	spin_lock_init(&intr->irq_lock);
 
 exit:

+ 1 - 9
msm/sde/sde_hw_interrupts.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
  */
 
@@ -170,14 +170,6 @@ struct sde_hw_intr_ops {
 			void (*cbfunc)(void *arg, int irq_idx),
 			void *arg);
 
-	/**
-	 * get_interrupt_statuses - Gets and store value from all interrupt
-	 *                          status registers that are currently fired.
-	 * @intr:	HW interrupt handle
-	 */
-	void (*get_interrupt_statuses)(
-			struct sde_hw_intr *intr);
-
 	/**
 	 * clear_interrupt_status - Clears HW interrupt status based on given
 	 *                          lookup IRQ index