18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology 48c2ecf20Sopenharmony_ci * Author: Fuxin Zhang, zhangfx@lemote.com 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#include <linux/delay.h> 78c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <loongson.h> 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci * the first level int-handler will jump here if it is a bonito irq 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_civoid bonito_irqdispatch(void) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci u32 int_status; 168c2ecf20Sopenharmony_ci int i; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci /* workaround the IO dma problem: let cpu looping to allow DMA finish */ 198c2ecf20Sopenharmony_ci int_status = LOONGSON_INTISR; 208c2ecf20Sopenharmony_ci while (int_status & (1 << 10)) { 218c2ecf20Sopenharmony_ci udelay(1); 228c2ecf20Sopenharmony_ci int_status = LOONGSON_INTISR; 238c2ecf20Sopenharmony_ci } 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci /* Get pending sources, masked by current enables */ 268c2ecf20Sopenharmony_ci int_status = LOONGSON_INTISR & LOONGSON_INTEN; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci if (int_status) { 298c2ecf20Sopenharmony_ci i = __ffs(int_status); 308c2ecf20Sopenharmony_ci do_IRQ(LOONGSON_IRQ_BASE + i); 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ciasmlinkage void plat_irq_dispatch(void) 358c2ecf20Sopenharmony_ci{ 368c2ecf20Sopenharmony_ci unsigned int pending; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci pending = read_c0_cause() & read_c0_status() & ST0_IM; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci /* machine-specific plat_irq_dispatch */ 418c2ecf20Sopenharmony_ci mach_irq_dispatch(pending); 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_civoid __init arch_init_irq(void) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci /* 478c2ecf20Sopenharmony_ci * Clear all of the interrupts while we change the able around a bit. 488c2ecf20Sopenharmony_ci * int-handler is not on bootstrap 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_ci clear_c0_status(ST0_IM | ST0_BEV); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci /* no steer */ 538c2ecf20Sopenharmony_ci LOONGSON_INTSTEER = 0; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci /* 568c2ecf20Sopenharmony_ci * Mask out all interrupt by writing "1" to all bit position in 578c2ecf20Sopenharmony_ci * the interrupt reset reg. 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_ci LOONGSON_INTENCLR = ~0; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* machine specific irq init */ 628c2ecf20Sopenharmony_ci mach_init_irq(); 638c2ecf20Sopenharmony_ci} 64