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