]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
irqchip/loongson-eiointc: Adjust irqchip driver for 32BIT/64BIT
authorHuacai Chen <chenhuacai@loongson.cn>
Tue, 13 Jan 2026 08:59:36 +0000 (16:59 +0800)
committerThomas Gleixner <tglx@kernel.org>
Sun, 18 Jan 2026 13:39:17 +0000 (14:39 +0100)
iocsr_read64()/iocsr_write64() are only available on 64BIT LoongArch
platform, so add and use a pair of helpers, i.e. read_isr()/write_isr()
instead to make the driver work on both 32BIT and 64BIT platforms.

This makes eoiintc_enable() a no-op for 32-bit as it is only required on
64-bit systems.

[ tglx: Make the helpers inline and fixup the variable declaration order ]

Co-developed-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Link: https://patch.msgid.link/20260113085940.3344837-4-chenhuacai@loongson.cn
drivers/irqchip/irq-loongson-eiointc.c

index ad2105685b48b4c09a1eb9ecd286e3fd07aa93a0..37e7e1f9bbe3a46ab19061cd38bd1ff06724e657 100644 (file)
@@ -37,9 +37,9 @@
 #define  EXTIOI_ENABLE_INT_ENCODE      BIT(2)
 #define  EXTIOI_ENABLE_CPU_ENCODE      BIT(3)
 
-#define VEC_REG_COUNT          4
-#define VEC_COUNT_PER_REG      64
-#define VEC_COUNT              (VEC_REG_COUNT * VEC_COUNT_PER_REG)
+#define VEC_COUNT              256
+#define VEC_COUNT_PER_REG      BITS_PER_LONG
+#define VEC_REG_COUNT          (VEC_COUNT / BITS_PER_LONG)
 #define VEC_REG_IDX(irq_id)    ((irq_id) / VEC_COUNT_PER_REG)
 #define VEC_REG_BIT(irq_id)     ((irq_id) % VEC_COUNT_PER_REG)
 #define EIOINTC_ALL_ENABLE     0xffffffff
@@ -85,11 +85,13 @@ static struct eiointc_priv *eiointc_priv[MAX_IO_PICS];
 
 static void eiointc_enable(void)
 {
+#ifdef CONFIG_MACH_LOONGSON64
        uint64_t misc;
 
        misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
        misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
        iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
+#endif
 }
 
 static int cpu_to_eio_node(int cpu)
@@ -281,12 +283,34 @@ static int eiointc_router_init(unsigned int cpu)
        return 0;
 }
 
+#if VEC_COUNT_PER_REG == 32
+static inline unsigned long read_isr(int i)
+{
+       return iocsr_read32(EIOINTC_REG_ISR + (i << 2));
+}
+
+static inline void write_isr(int i, unsigned long val)
+{
+       iocsr_write32(val, EIOINTC_REG_ISR + (i << 2));
+}
+#else
+static inline unsigned long read_isr(int i)
+{
+       return iocsr_read64(EIOINTC_REG_ISR + (i << 3));
+}
+
+static inline void write_isr(int i, unsigned long val)
+{
+       iocsr_write64(val, EIOINTC_REG_ISR + (i << 3));
+}
+#endif
+
 static void eiointc_irq_dispatch(struct irq_desc *desc)
 {
        struct eiointc_ip_route *info = irq_desc_get_handler_data(desc);
        struct irq_chip *chip = irq_desc_get_chip(desc);
+       unsigned long pending;
        bool handled = false;
-       u64 pending;
        int i;
 
        chained_irq_enter(chip, desc);
@@ -299,14 +323,14 @@ static void eiointc_irq_dispatch(struct irq_desc *desc)
         * read ISR for these 64 interrupt vectors rather than all vectors
         */
        for (i = info->start; i < info->end; i++) {
-               pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3));
+               pending = read_isr(i);
 
                /* Skip handling if pending bitmap is zero */
                if (!pending)
                        continue;
 
                /* Clear the IRQs */
-               iocsr_write64(pending, EIOINTC_REG_ISR + (i << 3));
+               write_isr(i, pending);
                while (pending) {
                        int bit = __ffs(pending);
                        int irq = bit + VEC_COUNT_PER_REG * i;