irqchip: gic-v3: support to get pending irqs and highprio irq
Add APIs to show pending interrupts in GIC, and next highest
priority interrupt on the current cpu.
Change-Id: Icde27deb7f0a32450ff8f5296e6a175b3559b7af
Signed-off-by: Lingutla Chandrasekhar <clingutla@codeaurora.org>
diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 6ebd2c3..f1ace59 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -21,6 +21,7 @@
#include <asm/sysreg.h>
#define ICC_EOIR1_EL1 sys_reg(3, 0, 12, 12, 1)
+#define ICC_HPPIR1_EL1 sys_reg(3, 0, 12, 12, 2)
#define ICC_DIR_EL1 sys_reg(3, 0, 12, 11, 1)
#define ICC_IAR1_EL1 sys_reg(3, 0, 12, 12, 0)
#define ICC_SGI1R_EL1 sys_reg(3, 0, 12, 11, 5)
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 779001e..01f9435 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -132,6 +132,45 @@
}
#endif
+/*
+ * gic_show_pending_irq - Shows the pending interrupts
+ * Note: Interrupts should be disabled on the cpu from which
+ * this is called to get accurate list of pending interrupts.
+ */
+void gic_show_pending_irqs(void)
+{
+ void __iomem *base;
+ u32 pending[32], enabled;
+ unsigned int j;
+
+ base = gic_data.dist_base;
+ for (j = 0; j * 32 < gic_data.irq_nr; j++) {
+ enabled = readl_relaxed(base +
+ GICD_ISENABLER + j * 4);
+ pending[j] = readl_relaxed(base +
+ GICD_ISPENDR + j * 4);
+ pending[j] &= enabled;
+ pr_err("Pending irqs[%d] %x\n", j, pending[j]);
+ }
+}
+
+/*
+ * get_gic_highpri_irq - Returns next high priority interrupt on current CPU
+ */
+unsigned int get_gic_highpri_irq(void)
+{
+ unsigned long flags;
+ unsigned int val = 0;
+
+ local_irq_save(flags);
+ val = read_gicreg(ICC_HPPIR1_EL1);
+ local_irq_restore(flags);
+
+ if (val >= 1020)
+ return 0;
+ return val;
+}
+
static void gic_enable_redist(bool enable)
{
void __iomem *rbase;
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index b7e3431..c122409 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -450,6 +450,8 @@
return !!(val & ICC_SRE_EL1_SRE);
}
+void gic_show_pending_irqs(void);
+unsigned int get_gic_highpri_irq(void);
#endif
#endif