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 void __init mach_init_irq(void) 3971e2f4ddSJiaxun Yang { 40ac8fd122Safzal mohammed int irq; 41ac8fd122Safzal mohammed 4271e2f4ddSJiaxun Yang /* init all controller 4371e2f4ddSJiaxun Yang * 0-15 ------> i8259 interrupt 4471e2f4ddSJiaxun Yang * 16-23 ------> mips cpu interrupt 4571e2f4ddSJiaxun Yang * 32-63 ------> bonito irq 4671e2f4ddSJiaxun Yang */ 4771e2f4ddSJiaxun Yang 4871e2f4ddSJiaxun Yang /* most bonito irq should be level triggered */ 4971e2f4ddSJiaxun Yang LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | 5071e2f4ddSJiaxun Yang LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; 5171e2f4ddSJiaxun Yang 5271e2f4ddSJiaxun Yang /* Sets the first-level interrupt dispatcher. */ 5371e2f4ddSJiaxun Yang mips_cpu_irq_init(); 5471e2f4ddSJiaxun Yang init_i8259_irqs(); 5571e2f4ddSJiaxun Yang bonito_irq_init(); 5671e2f4ddSJiaxun Yang 5771e2f4ddSJiaxun Yang /* bonito irq at IP2 */ 58ac8fd122Safzal mohammed irq = MIPS_CPU_IRQ_BASE + 2; 59ac8fd122Safzal mohammed if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL)) 60ac8fd122Safzal mohammed pr_err("Failed to request irq %d (cascade)\n", irq); 6171e2f4ddSJiaxun Yang /* 8259 irq at IP5 */ 62ac8fd122Safzal mohammed irq = MIPS_CPU_IRQ_BASE + 5; 63ac8fd122Safzal mohammed if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL)) 64ac8fd122Safzal mohammed pr_err("Failed to request irq %d (cascade)\n", irq); 6571e2f4ddSJiaxun Yang } 66