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