xref: /OK3568_Linux_fs/kernel/arch/mips/loongson2ef/fuloong-2e/irq.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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