Skip to content

Commit 61fb5e5

Browse files
chenhuacaiThomas Gleixner
authored andcommitted
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 <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
1 parent 57e0513 commit 61fb5e5

1 file changed

Lines changed: 30 additions & 6 deletions

File tree

drivers/irqchip/irq-loongson-eiointc.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@
3737
#define EXTIOI_ENABLE_INT_ENCODE BIT(2)
3838
#define EXTIOI_ENABLE_CPU_ENCODE BIT(3)
3939

40-
#define VEC_REG_COUNT 4
41-
#define VEC_COUNT_PER_REG 64
42-
#define VEC_COUNT (VEC_REG_COUNT * VEC_COUNT_PER_REG)
40+
#define VEC_COUNT 256
41+
#define VEC_COUNT_PER_REG BITS_PER_LONG
42+
#define VEC_REG_COUNT (VEC_COUNT / BITS_PER_LONG)
4343
#define VEC_REG_IDX(irq_id) ((irq_id) / VEC_COUNT_PER_REG)
4444
#define VEC_REG_BIT(irq_id) ((irq_id) % VEC_COUNT_PER_REG)
4545
#define EIOINTC_ALL_ENABLE 0xffffffff
@@ -85,11 +85,13 @@ static struct eiointc_priv *eiointc_priv[MAX_IO_PICS];
8585

8686
static void eiointc_enable(void)
8787
{
88+
#ifdef CONFIG_MACH_LOONGSON64
8889
uint64_t misc;
8990

9091
misc = iocsr_read64(LOONGARCH_IOCSR_MISC_FUNC);
9192
misc |= IOCSR_MISC_FUNC_EXT_IOI_EN;
9293
iocsr_write64(misc, LOONGARCH_IOCSR_MISC_FUNC);
94+
#endif
9395
}
9496

9597
static int cpu_to_eio_node(int cpu)
@@ -281,12 +283,34 @@ static int eiointc_router_init(unsigned int cpu)
281283
return 0;
282284
}
283285

286+
#if VEC_COUNT_PER_REG == 32
287+
static inline unsigned long read_isr(int i)
288+
{
289+
return iocsr_read32(EIOINTC_REG_ISR + (i << 2));
290+
}
291+
292+
static inline void write_isr(int i, unsigned long val)
293+
{
294+
iocsr_write32(val, EIOINTC_REG_ISR + (i << 2));
295+
}
296+
#else
297+
static inline unsigned long read_isr(int i)
298+
{
299+
return iocsr_read64(EIOINTC_REG_ISR + (i << 3));
300+
}
301+
302+
static inline void write_isr(int i, unsigned long val)
303+
{
304+
iocsr_write64(val, EIOINTC_REG_ISR + (i << 3));
305+
}
306+
#endif
307+
284308
static void eiointc_irq_dispatch(struct irq_desc *desc)
285309
{
286310
struct eiointc_ip_route *info = irq_desc_get_handler_data(desc);
287311
struct irq_chip *chip = irq_desc_get_chip(desc);
312+
unsigned long pending;
288313
bool handled = false;
289-
u64 pending;
290314
int i;
291315

292316
chained_irq_enter(chip, desc);
@@ -299,14 +323,14 @@ static void eiointc_irq_dispatch(struct irq_desc *desc)
299323
* read ISR for these 64 interrupt vectors rather than all vectors
300324
*/
301325
for (i = info->start; i < info->end; i++) {
302-
pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3));
326+
pending = read_isr(i);
303327

304328
/* Skip handling if pending bitmap is zero */
305329
if (!pending)
306330
continue;
307331

308332
/* Clear the IRQs */
309-
iocsr_write64(pending, EIOINTC_REG_ISR + (i << 3));
333+
write_isr(i, pending);
310334
while (pending) {
311335
int bit = __ffs(pending);
312336
int irq = bit + VEC_COUNT_PER_REG * i;

0 commit comments

Comments
 (0)