162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology 462306a36Sopenharmony_ci * Author: Fuxin Zhang, zhangfx@lemote.com 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#include <linux/interrupt.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <asm/irq_cpu.h> 962306a36Sopenharmony_ci#include <asm/i8259.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <loongson.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistatic void i8259_irqdispatch(void) 1462306a36Sopenharmony_ci{ 1562306a36Sopenharmony_ci int irq; 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci irq = i8259_irq(); 1862306a36Sopenharmony_ci if (irq >= 0) 1962306a36Sopenharmony_ci do_IRQ(irq); 2062306a36Sopenharmony_ci else 2162306a36Sopenharmony_ci spurious_interrupt(); 2262306a36Sopenharmony_ci} 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ciasmlinkage void mach_irq_dispatch(unsigned int pending) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci if (pending & CAUSEF_IP7) 2762306a36Sopenharmony_ci do_IRQ(MIPS_CPU_IRQ_BASE + 7); 2862306a36Sopenharmony_ci else if (pending & CAUSEF_IP6) /* perf counter loverflow */ 2962306a36Sopenharmony_ci return; 3062306a36Sopenharmony_ci else if (pending & CAUSEF_IP5) 3162306a36Sopenharmony_ci i8259_irqdispatch(); 3262306a36Sopenharmony_ci else if (pending & CAUSEF_IP2) 3362306a36Sopenharmony_ci bonito_irqdispatch(); 3462306a36Sopenharmony_ci else 3562306a36Sopenharmony_ci spurious_interrupt(); 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_civoid __init mach_init_irq(void) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci int irq; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci /* init all controller 4362306a36Sopenharmony_ci * 0-15 ------> i8259 interrupt 4462306a36Sopenharmony_ci * 16-23 ------> mips cpu interrupt 4562306a36Sopenharmony_ci * 32-63 ------> bonito irq 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* most bonito irq should be level triggered */ 4962306a36Sopenharmony_ci LOONGSON_INTEDGE = LOONGSON_ICU_SYSTEMERR | LOONGSON_ICU_MASTERERR | 5062306a36Sopenharmony_ci LOONGSON_ICU_RETRYERR | LOONGSON_ICU_MBOXES; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* Sets the first-level interrupt dispatcher. */ 5362306a36Sopenharmony_ci mips_cpu_irq_init(); 5462306a36Sopenharmony_ci init_i8259_irqs(); 5562306a36Sopenharmony_ci bonito_irq_init(); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci /* bonito irq at IP2 */ 5862306a36Sopenharmony_ci irq = MIPS_CPU_IRQ_BASE + 2; 5962306a36Sopenharmony_ci if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL)) 6062306a36Sopenharmony_ci pr_err("Failed to request irq %d (cascade)\n", irq); 6162306a36Sopenharmony_ci /* 8259 irq at IP5 */ 6262306a36Sopenharmony_ci irq = MIPS_CPU_IRQ_BASE + 5; 6362306a36Sopenharmony_ci if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL)) 6462306a36Sopenharmony_ci pr_err("Failed to request irq %d (cascade)\n", irq); 6562306a36Sopenharmony_ci} 66