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 
i8259_irqdispatch(void)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 
mach_irq_dispatch(unsigned int pending)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 */
29*e2589589SViresh Kumar 		return;
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 
mach_init_irq(void)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