xref: /linux/arch/mips/loongson2ef/common/irq.c (revision 987b741c52c7c6c68d46fbaeb95b8d1087f10b7f)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2007 Lemote Inc. & Institute of Computing Technology
4  * Author: Fuxin Zhang, zhangfx@lemote.com
5  */
6 #include <linux/delay.h>
7 #include <linux/interrupt.h>
8 
9 #include <loongson.h>
10 /*
11  * the first level int-handler will jump here if it is a bonito irq
12  */
13 void bonito_irqdispatch(void)
14 {
15 	u32 int_status;
16 	int i;
17 
18 	/* workaround the IO dma problem: let cpu looping to allow DMA finish */
19 	int_status = LOONGSON_INTISR;
20 	while (int_status & (1 << 10)) {
21 		udelay(1);
22 		int_status = LOONGSON_INTISR;
23 	}
24 
25 	/* Get pending sources, masked by current enables */
26 	int_status = LOONGSON_INTISR & LOONGSON_INTEN;
27 
28 	if (int_status) {
29 		i = __ffs(int_status);
30 		do_IRQ(LOONGSON_IRQ_BASE + i);
31 	}
32 }
33 
34 asmlinkage void plat_irq_dispatch(void)
35 {
36 	unsigned int pending;
37 
38 	pending = read_c0_cause() & read_c0_status() & ST0_IM;
39 
40 	/* machine-specific plat_irq_dispatch */
41 	mach_irq_dispatch(pending);
42 }
43 
44 void __init arch_init_irq(void)
45 {
46 	/*
47 	 * Clear all of the interrupts while we change the able around a bit.
48 	 * int-handler is not on bootstrap
49 	 */
50 	clear_c0_status(ST0_IM | ST0_BEV);
51 
52 	/* no steer */
53 	LOONGSON_INTSTEER = 0;
54 
55 	/*
56 	 * Mask out all interrupt by writing "1" to all bit position in
57 	 * the interrupt reset reg.
58 	 */
59 	LOONGSON_INTENCLR = ~0;
60 
61 	/* machine specific irq init */
62 	mach_init_irq();
63 }
64