1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
4*4882a593Smuzhiyun * Author: Fuxin Zhang, zhangfx@lemote.com
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun #include <linux/interrupt.h>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <asm/irq_cpu.h>
9*4882a593Smuzhiyun #include <asm/i8259.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <loongson.h>
12*4882a593Smuzhiyun
i8259_irqdispatch(void)13*4882a593Smuzhiyun static void i8259_irqdispatch(void)
14*4882a593Smuzhiyun {
15*4882a593Smuzhiyun int irq;
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun irq = i8259_irq();
18*4882a593Smuzhiyun if (irq >= 0)
19*4882a593Smuzhiyun do_IRQ(irq);
20*4882a593Smuzhiyun else
21*4882a593Smuzhiyun spurious_interrupt();
22*4882a593Smuzhiyun }
23*4882a593Smuzhiyun
mach_irq_dispatch(unsigned int pending)24*4882a593Smuzhiyun asmlinkage void mach_irq_dispatch(unsigned int pending)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun if (pending & CAUSEF_IP7)
27*4882a593Smuzhiyun do_IRQ(MIPS_CPU_IRQ_BASE + 7);
28*4882a593Smuzhiyun else if (pending & CAUSEF_IP6) /* perf counter loverflow */
29*4882a593Smuzhiyun do_perfcnt_IRQ();
30*4882a593Smuzhiyun else if (pending & CAUSEF_IP5)
31*4882a593Smuzhiyun i8259_irqdispatch();
32*4882a593Smuzhiyun else if (pending & CAUSEF_IP2)
33*4882a593Smuzhiyun bonito_irqdispatch();
34*4882a593Smuzhiyun else
35*4882a593Smuzhiyun spurious_interrupt();
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
mach_init_irq(void)38*4882a593Smuzhiyun void __init mach_init_irq(void)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun int irq;
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun /* init all controller
43*4882a593Smuzhiyun * 0-15 ------> i8259 interrupt
44*4882a593Smuzhiyun * 16-23 ------> mips cpu interrupt
45*4882a593Smuzhiyun * 32-63 ------> bonito irq
46*4882a593Smuzhiyun */
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /* most bonito irq should be level triggered */
49*4882a593Smuzhiyun LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR |
50*4882a593Smuzhiyun LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun /* Sets the first-level interrupt dispatcher. */
53*4882a593Smuzhiyun mips_cpu_irq_init();
54*4882a593Smuzhiyun init_i8259_irqs();
55*4882a593Smuzhiyun bonito_irq_init();
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun /* bonito irq at IP2 */
58*4882a593Smuzhiyun irq = MIPS_CPU_IRQ_BASE + 2;
59*4882a593Smuzhiyun if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL))
60*4882a593Smuzhiyun pr_err("Failed to request irq %d (cascade)\n", irq);
61*4882a593Smuzhiyun /* 8259 irq at IP5 */
62*4882a593Smuzhiyun irq = MIPS_CPU_IRQ_BASE + 5;
63*4882a593Smuzhiyun if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL))
64*4882a593Smuzhiyun pr_err("Failed to request irq %d (cascade)\n", irq);
65*4882a593Smuzhiyun }
66