浏览代码

IRQCHIP: irq-mips-gic: Add support for CM3 64-bit timer irqs

CM3 uses a 64-bit counter and compare registers so add support for
them in the GIC counter interrupt.

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Andrew Bresticker <abrestic@chromium.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/10648/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Markos Chandras 10 年之前
父节点
当前提交
6f50c83529
共有 2 个文件被更改,包括 28 次插入9 次删除
  1. 24 9
      drivers/irqchip/irq-mips-gic.c
  2. 4 0
      include/linux/irqchip/mips-gic.h

+ 24 - 9
drivers/irqchip/irq-mips-gic.c

@@ -140,6 +140,9 @@ cycle_t gic_read_count(void)
 {
 {
 	unsigned int hi, hi2, lo;
 	unsigned int hi, hi2, lo;
 
 
+	if (mips_cm_is64)
+		return (cycle_t)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER));
+
 	do {
 	do {
 		hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
 		hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32));
 		lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
 		lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00));
@@ -162,10 +165,14 @@ unsigned int gic_get_count_width(void)
 
 
 void gic_write_compare(cycle_t cnt)
 void gic_write_compare(cycle_t cnt)
 {
 {
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
-				(int)(cnt >> 32));
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
-				(int)(cnt & 0xffffffff));
+	if (mips_cm_is64) {
+		gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt);
+	} else {
+		gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI),
+					(int)(cnt >> 32));
+		gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO),
+					(int)(cnt & 0xffffffff));
+	}
 }
 }
 
 
 void gic_write_cpu_compare(cycle_t cnt, int cpu)
 void gic_write_cpu_compare(cycle_t cnt, int cpu)
@@ -174,11 +181,16 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu)
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
-	gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
-	gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
-				(int)(cnt >> 32));
-	gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
-				(int)(cnt & 0xffffffff));
+	gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
+
+	if (mips_cm_is64) {
+		gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt);
+	} else {
+		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
+					(int)(cnt >> 32));
+		gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
+					(int)(cnt & 0xffffffff));
+	}
 
 
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
@@ -187,6 +199,9 @@ cycle_t gic_read_compare(void)
 {
 {
 	unsigned int hi, lo;
 	unsigned int hi, lo;
 
 
+	if (mips_cm_is64)
+		return (cycle_t)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE));
+
 	hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
 	hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI));
 	lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
 	lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO));
 
 

+ 4 - 0
include/linux/irqchip/mips-gic.h

@@ -41,6 +41,8 @@
 
 
 /* Shared Global Counter */
 /* Shared Global Counter */
 #define GIC_SH_COUNTER_31_00_OFS	0x0010
 #define GIC_SH_COUNTER_31_00_OFS	0x0010
+/* 64-bit counter register for CM3 */
+#define GIC_SH_COUNTER_OFS		GIC_SH_COUNTER_31_00_OFS
 #define GIC_SH_COUNTER_63_32_OFS	0x0014
 #define GIC_SH_COUNTER_63_32_OFS	0x0014
 #define GIC_SH_REVISIONID_OFS		0x0020
 #define GIC_SH_REVISIONID_OFS		0x0020
 
 
@@ -104,6 +106,8 @@
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
 #define GIC_VPE_WD_COUNT0_OFS		0x0094
 #define GIC_VPE_WD_INITIAL0_OFS		0x0098
 #define GIC_VPE_WD_INITIAL0_OFS		0x0098
 #define GIC_VPE_COMPARE_LO_OFS		0x00a0
 #define GIC_VPE_COMPARE_LO_OFS		0x00a0
+/* 64-bit Compare register on CM3 */
+#define GIC_VPE_COMPARE_OFS		GIC_VPE_COMPARE_LO_OFS
 #define GIC_VPE_COMPARE_HI_OFS		0x00a4
 #define GIC_VPE_COMPARE_HI_OFS		0x00a4
 
 
 #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS	0x0100
 #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS	0x0100