171e2f4ddSJiaxun Yang // SPDX-License-Identifier: GPL-2.0-or-later 271e2f4ddSJiaxun Yang /* 371e2f4ddSJiaxun Yang * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology 471e2f4ddSJiaxun Yang * Author: Fuxin Zhang, zhangfx@lemote.com 571e2f4ddSJiaxun Yang */ 671e2f4ddSJiaxun Yang #include <linux/interrupt.h> 771e2f4ddSJiaxun Yang 871e2f4ddSJiaxun Yang #include <asm/irq_cpu.h> 971e2f4ddSJiaxun Yang #include <asm/i8259.h> 1071e2f4ddSJiaxun Yang 1171e2f4ddSJiaxun Yang #include <loongson.h> 1271e2f4ddSJiaxun Yang 1371e2f4ddSJiaxun Yang static void i8259_irqdispatch(void) 1471e2f4ddSJiaxun Yang { 1571e2f4ddSJiaxun Yang int irq; 1671e2f4ddSJiaxun Yang 1771e2f4ddSJiaxun Yang irq = i8259_irq(); 1871e2f4ddSJiaxun Yang if (irq >= 0) 1971e2f4ddSJiaxun Yang do_IRQ(irq); 2071e2f4ddSJiaxun Yang else 2171e2f4ddSJiaxun Yang spurious_interrupt(); 2271e2f4ddSJiaxun Yang } 2371e2f4ddSJiaxun Yang 2471e2f4ddSJiaxun Yang asmlinkage void mach_irq_dispatch(unsigned int pending) 2571e2f4ddSJiaxun Yang { 2671e2f4ddSJiaxun Yang if (pending & CAUSEF_IP7) 2771e2f4ddSJiaxun Yang do_IRQ(MIPS_CPU_IRQ_BASE + 7); 2871e2f4ddSJiaxun Yang else if (pending & CAUSEF_IP6) /* perf counter loverflow */ 2971e2f4ddSJiaxun Yang do_perfcnt_IRQ(); 3071e2f4ddSJiaxun Yang else if (pending & CAUSEF_IP5) 3171e2f4ddSJiaxun Yang i8259_irqdispatch(); 3271e2f4ddSJiaxun Yang else if (pending & CAUSEF_IP2) 3371e2f4ddSJiaxun Yang bonito_irqdispatch(); 3471e2f4ddSJiaxun Yang else 3571e2f4ddSJiaxun Yang spurious_interrupt(); 3671e2f4ddSJiaxun Yang } 3771e2f4ddSJiaxun Yang 3871e2f4ddSJiaxun Yang static struct irqaction cascade_irqaction = { 3971e2f4ddSJiaxun Yang .handler = no_action, 4071e2f4ddSJiaxun Yang .name = "cascade", 4171e2f4ddSJiaxun Yang .flags = IRQF_NO_THREAD, 4271e2f4ddSJiaxun Yang }; 4371e2f4ddSJiaxun Yang 4471e2f4ddSJiaxun Yang void __init mach_init_irq(void) 4571e2f4ddSJiaxun Yang { 4671e2f4ddSJiaxun Yang /* init all controller 4771e2f4ddSJiaxun Yang * 0-15 ------> i8259 interrupt 4871e2f4ddSJiaxun Yang * 16-23 ------> mips cpu interrupt 4971e2f4ddSJiaxun Yang * 32-63 ------> bonito irq 5071e2f4ddSJiaxun Yang */ 5171e2f4ddSJiaxun Yang 5271e2f4ddSJiaxun Yang /* most bonito irq should be level triggered */ 5371e2f4ddSJiaxun Yang LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | 5471e2f4ddSJiaxun Yang LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; 5571e2f4ddSJiaxun Yang 5671e2f4ddSJiaxun Yang /* Sets the first-level interrupt dispatcher. */ 5771e2f4ddSJiaxun Yang mips_cpu_irq_init(); 5871e2f4ddSJiaxun Yang init_i8259_irqs(); 5971e2f4ddSJiaxun Yang bonito_irq_init(); 6071e2f4ddSJiaxun Yang 6171e2f4ddSJiaxun Yang /* bonito irq at IP2 */ 6271e2f4ddSJiaxun Yang setup_irq(MIPS_CPU_IRQ_BASE + 2, &cascade_irqaction); 6371e2f4ddSJiaxun Yang /* 8259 irq at IP5 */ 6471e2f4ddSJiaxun Yang setup_irq(MIPS_CPU_IRQ_BASE + 5, &cascade_irqaction); 6571e2f4ddSJiaxun Yang } 66