1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) NEC Electronics Corporation 2004-2006
5 * This file is based on the arch/mips/ddb5xxx/ddb5477/irq.c
7 * Copyright 2001 MontaVista Software Inc.
9 #include <linux/init.h>
10 #include <linux/interrupt.h>
11 #include <linux/irq.h>
12 #include <linux/types.h>
13 #include <linux/ptrace.h>
14 #include <linux/delay.h>
16 #include <asm/irq_cpu.h>
17 #include <asm/mipsregs.h>
18 #include <asm/addrspace.h>
19 #include <asm/bootinfo.h>
21 #include <asm/emma/emma2rh.h>
23 static void emma2rh_irq_enable(struct irq_data
*d
)
25 unsigned int irq
= d
->irq
- EMMA2RH_IRQ_BASE
;
26 u32 reg_value
, reg_bitmask
, reg_index
;
28 reg_index
= EMMA2RH_BHIF_INT_EN_0
+
29 (EMMA2RH_BHIF_INT_EN_1
- EMMA2RH_BHIF_INT_EN_0
) * (irq
/ 32);
30 reg_value
= emma2rh_in32(reg_index
);
31 reg_bitmask
= 0x1 << (irq
% 32);
32 emma2rh_out32(reg_index
, reg_value
| reg_bitmask
);
35 static void emma2rh_irq_disable(struct irq_data
*d
)
37 unsigned int irq
= d
->irq
- EMMA2RH_IRQ_BASE
;
38 u32 reg_value
, reg_bitmask
, reg_index
;
40 reg_index
= EMMA2RH_BHIF_INT_EN_0
+
41 (EMMA2RH_BHIF_INT_EN_1
- EMMA2RH_BHIF_INT_EN_0
) * (irq
/ 32);
42 reg_value
= emma2rh_in32(reg_index
);
43 reg_bitmask
= 0x1 << (irq
% 32);
44 emma2rh_out32(reg_index
, reg_value
& ~reg_bitmask
);
47 struct irq_chip emma2rh_irq_controller
= {
48 .name
= "emma2rh_irq",
49 .irq_mask
= emma2rh_irq_disable
,
50 .irq_unmask
= emma2rh_irq_enable
,
53 void emma2rh_irq_init(void)
57 for (i
= 0; i
< NUM_EMMA2RH_IRQ
; i
++)
58 irq_set_chip_and_handler_name(EMMA2RH_IRQ_BASE
+ i
,
59 &emma2rh_irq_controller
,
60 handle_level_irq
, "level");
63 static void emma2rh_sw_irq_enable(struct irq_data
*d
)
65 unsigned int irq
= d
->irq
- EMMA2RH_SW_IRQ_BASE
;
68 reg
= emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN
);
70 emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN
, reg
);
73 static void emma2rh_sw_irq_disable(struct irq_data
*d
)
75 unsigned int irq
= d
->irq
- EMMA2RH_SW_IRQ_BASE
;
78 reg
= emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN
);
80 emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN
, reg
);
83 struct irq_chip emma2rh_sw_irq_controller
= {
84 .name
= "emma2rh_sw_irq",
85 .irq_mask
= emma2rh_sw_irq_disable
,
86 .irq_unmask
= emma2rh_sw_irq_enable
,
89 void emma2rh_sw_irq_init(void)
93 for (i
= 0; i
< NUM_EMMA2RH_IRQ_SW
; i
++)
94 irq_set_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE
+ i
,
95 &emma2rh_sw_irq_controller
,
96 handle_level_irq
, "level");
99 static void emma2rh_gpio_irq_enable(struct irq_data
*d
)
101 unsigned int irq
= d
->irq
- EMMA2RH_GPIO_IRQ_BASE
;
104 reg
= emma2rh_in32(EMMA2RH_GPIO_INT_MASK
);
106 emma2rh_out32(EMMA2RH_GPIO_INT_MASK
, reg
);
109 static void emma2rh_gpio_irq_disable(struct irq_data
*d
)
111 unsigned int irq
= d
->irq
- EMMA2RH_GPIO_IRQ_BASE
;
114 reg
= emma2rh_in32(EMMA2RH_GPIO_INT_MASK
);
116 emma2rh_out32(EMMA2RH_GPIO_INT_MASK
, reg
);
119 static void emma2rh_gpio_irq_ack(struct irq_data
*d
)
121 unsigned int irq
= d
->irq
- EMMA2RH_GPIO_IRQ_BASE
;
123 emma2rh_out32(EMMA2RH_GPIO_INT_ST
, ~(1 << irq
));
126 static void emma2rh_gpio_irq_mask_ack(struct irq_data
*d
)
128 unsigned int irq
= d
->irq
- EMMA2RH_GPIO_IRQ_BASE
;
131 emma2rh_out32(EMMA2RH_GPIO_INT_ST
, ~(1 << irq
));
133 reg
= emma2rh_in32(EMMA2RH_GPIO_INT_MASK
);
135 emma2rh_out32(EMMA2RH_GPIO_INT_MASK
, reg
);
138 struct irq_chip emma2rh_gpio_irq_controller
= {
139 .name
= "emma2rh_gpio_irq",
140 .irq_ack
= emma2rh_gpio_irq_ack
,
141 .irq_mask
= emma2rh_gpio_irq_disable
,
142 .irq_mask_ack
= emma2rh_gpio_irq_mask_ack
,
143 .irq_unmask
= emma2rh_gpio_irq_enable
,
146 void emma2rh_gpio_irq_init(void)
150 for (i
= 0; i
< NUM_EMMA2RH_IRQ_GPIO
; i
++)
151 irq_set_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE
+ i
,
152 &emma2rh_gpio_irq_controller
,
153 handle_edge_irq
, "edge");
156 static struct irqaction irq_cascade
= {
157 .handler
= no_action
,
158 .flags
= IRQF_NO_THREAD
,
165 * the first level int-handler will jump here if it is a emma2rh irq
167 void emma2rh_irq_dispatch(void)
173 intStatus
= emma2rh_in32(EMMA2RH_BHIF_INT_ST_0
) &
174 emma2rh_in32(EMMA2RH_BHIF_INT_EN_0
);
176 #ifdef EMMA2RH_SW_CASCADE
177 if (intStatus
& (1UL << EMMA2RH_SW_CASCADE
)) {
179 swIntStatus
= emma2rh_in32(EMMA2RH_BHIF_SW_INT
)
180 & emma2rh_in32(EMMA2RH_BHIF_SW_INT_EN
);
181 for (i
= 0, bitmask
= 1; i
< 32; i
++, bitmask
<<= 1) {
182 if (swIntStatus
& bitmask
) {
183 do_IRQ(EMMA2RH_SW_IRQ_BASE
+ i
);
188 /* Skip S/W interrupt */
189 intStatus
&= ~(1UL << EMMA2RH_SW_CASCADE
);
192 for (i
= 0, bitmask
= 1; i
< 32; i
++, bitmask
<<= 1) {
193 if (intStatus
& bitmask
) {
194 do_IRQ(EMMA2RH_IRQ_BASE
+ i
);
199 intStatus
= emma2rh_in32(EMMA2RH_BHIF_INT_ST_1
) &
200 emma2rh_in32(EMMA2RH_BHIF_INT_EN_1
);
202 #ifdef EMMA2RH_GPIO_CASCADE
203 if (intStatus
& (1UL << (EMMA2RH_GPIO_CASCADE
% 32))) {
205 gpioIntStatus
= emma2rh_in32(EMMA2RH_GPIO_INT_ST
)
206 & emma2rh_in32(EMMA2RH_GPIO_INT_MASK
);
207 for (i
= 0, bitmask
= 1; i
< 32; i
++, bitmask
<<= 1) {
208 if (gpioIntStatus
& bitmask
) {
209 do_IRQ(EMMA2RH_GPIO_IRQ_BASE
+ i
);
214 /* Skip GPIO interrupt */
215 intStatus
&= ~(1UL << (EMMA2RH_GPIO_CASCADE
% 32));
218 for (i
= 32, bitmask
= 1; i
< 64; i
++, bitmask
<<= 1) {
219 if (intStatus
& bitmask
) {
220 do_IRQ(EMMA2RH_IRQ_BASE
+ i
);
225 intStatus
= emma2rh_in32(EMMA2RH_BHIF_INT_ST_2
) &
226 emma2rh_in32(EMMA2RH_BHIF_INT_EN_2
);
228 for (i
= 64, bitmask
= 1; i
< 96; i
++, bitmask
<<= 1) {
229 if (intStatus
& bitmask
) {
230 do_IRQ(EMMA2RH_IRQ_BASE
+ i
);
236 void __init
arch_init_irq(void)
240 /* by default, interrupts are disabled. */
241 emma2rh_out32(EMMA2RH_BHIF_INT_EN_0
, 0);
242 emma2rh_out32(EMMA2RH_BHIF_INT_EN_1
, 0);
243 emma2rh_out32(EMMA2RH_BHIF_INT_EN_2
, 0);
244 emma2rh_out32(EMMA2RH_BHIF_INT1_EN_0
, 0);
245 emma2rh_out32(EMMA2RH_BHIF_INT1_EN_1
, 0);
246 emma2rh_out32(EMMA2RH_BHIF_INT1_EN_2
, 0);
247 emma2rh_out32(EMMA2RH_BHIF_SW_INT_EN
, 0);
249 clear_c0_status(0xff00);
250 set_c0_status(0x0400);
252 #define GPIO_PCI (0xf<<15)
253 /* setup GPIO interrupt for PCI interface */
254 /* direction input */
255 reg
= emma2rh_in32(EMMA2RH_GPIO_DIR
);
256 emma2rh_out32(EMMA2RH_GPIO_DIR
, reg
& ~GPIO_PCI
);
257 /* disable interrupt */
258 reg
= emma2rh_in32(EMMA2RH_GPIO_INT_MASK
);
259 emma2rh_out32(EMMA2RH_GPIO_INT_MASK
, reg
& ~GPIO_PCI
);
261 reg
= emma2rh_in32(EMMA2RH_GPIO_INT_MODE
);
262 emma2rh_out32(EMMA2RH_GPIO_INT_MODE
, reg
| GPIO_PCI
);
263 reg
= emma2rh_in32(EMMA2RH_GPIO_INT_CND_A
);
264 emma2rh_out32(EMMA2RH_GPIO_INT_CND_A
, reg
& (~GPIO_PCI
));
265 /* interrupt clear */
266 emma2rh_out32(EMMA2RH_GPIO_INT_ST
, ~GPIO_PCI
);
268 /* init all controllers */
270 emma2rh_sw_irq_init();
271 emma2rh_gpio_irq_init();
274 /* setup cascade interrupts */
275 setup_irq(EMMA2RH_IRQ_BASE
+ EMMA2RH_SW_CASCADE
, &irq_cascade
);
276 setup_irq(EMMA2RH_IRQ_BASE
+ EMMA2RH_GPIO_CASCADE
, &irq_cascade
);
277 setup_irq(MIPS_CPU_IRQ_BASE
+ 2, &irq_cascade
);
280 asmlinkage
void plat_irq_dispatch(void)
282 unsigned int pending
= read_c0_status() & read_c0_cause() & ST0_IM
;
284 if (pending
& STATUSF_IP7
)
285 do_IRQ(MIPS_CPU_IRQ_BASE
+ 7);
286 else if (pending
& STATUSF_IP2
)
287 emma2rh_irq_dispatch();
288 else if (pending
& STATUSF_IP1
)
289 do_IRQ(MIPS_CPU_IRQ_BASE
+ 1);
290 else if (pending
& STATUSF_IP0
)
291 do_IRQ(MIPS_CPU_IRQ_BASE
+ 0);
293 spurious_interrupt();