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/delay.h> 7*4882a593Smuzhiyun #include <linux/interrupt.h> 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <loongson.h> 10*4882a593Smuzhiyun /* 11*4882a593Smuzhiyun * the first level int-handler will jump here if it is a bonito irq 12*4882a593Smuzhiyun */ bonito_irqdispatch(void)13*4882a593Smuzhiyunvoid bonito_irqdispatch(void) 14*4882a593Smuzhiyun { 15*4882a593Smuzhiyun u32 int_status; 16*4882a593Smuzhiyun int i; 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* workaround the IO dma problem: let cpu looping to allow DMA finish */ 19*4882a593Smuzhiyun int_status = LOONGSON_INTISR; 20*4882a593Smuzhiyun while (int_status & (1 << 10)) { 21*4882a593Smuzhiyun udelay(1); 22*4882a593Smuzhiyun int_status = LOONGSON_INTISR; 23*4882a593Smuzhiyun } 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun /* Get pending sources, masked by current enables */ 26*4882a593Smuzhiyun int_status = LOONGSON_INTISR & LOONGSON_INTEN; 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun if (int_status) { 29*4882a593Smuzhiyun i = __ffs(int_status); 30*4882a593Smuzhiyun do_IRQ(LOONGSON_IRQ_BASE + i); 31*4882a593Smuzhiyun } 32*4882a593Smuzhiyun } 33*4882a593Smuzhiyun plat_irq_dispatch(void)34*4882a593Smuzhiyunasmlinkage void plat_irq_dispatch(void) 35*4882a593Smuzhiyun { 36*4882a593Smuzhiyun unsigned int pending; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun pending = read_c0_cause() & read_c0_status() & ST0_IM; 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun /* machine-specific plat_irq_dispatch */ 41*4882a593Smuzhiyun mach_irq_dispatch(pending); 42*4882a593Smuzhiyun } 43*4882a593Smuzhiyun arch_init_irq(void)44*4882a593Smuzhiyunvoid __init arch_init_irq(void) 45*4882a593Smuzhiyun { 46*4882a593Smuzhiyun /* 47*4882a593Smuzhiyun * Clear all of the interrupts while we change the able around a bit. 48*4882a593Smuzhiyun * int-handler is not on bootstrap 49*4882a593Smuzhiyun */ 50*4882a593Smuzhiyun clear_c0_status(ST0_IM | ST0_BEV); 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* no steer */ 53*4882a593Smuzhiyun LOONGSON_INTSTEER = 0; 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* 56*4882a593Smuzhiyun * Mask out all interrupt by writing "1" to all bit position in 57*4882a593Smuzhiyun * the interrupt reset reg. 58*4882a593Smuzhiyun */ 59*4882a593Smuzhiyun LOONGSON_INTENCLR = ~0; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun /* machine specific irq init */ 62*4882a593Smuzhiyun mach_init_irq(); 63*4882a593Smuzhiyun } 64