From 61fb5e517ec457c76211f03ab0b379882248706d Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 13 Jan 2026 16:59:36 +0800 Subject: [PATCH] irqchip/loongson-eiointc: Adjust irqchip driver for 32BIT/64BIT 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 Signed-off-by: Jiaxun Yang Signed-off-by: Huacai Chen Signed-off-by: Thomas Gleixner Link: https://patch.msgid.link/20260113085940.3344837-4-chenhuacai@loongson.cn --- drivers/irqchip/irq-loongson-eiointc.c | 36 +++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index ad2105685b48b..37e7e1f9bbe3a 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -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; -- 2.47.3