diff options
Diffstat (limited to 'arch/mips/sgi-ip27/ip27-irq.c')
-rw-r--r-- | arch/mips/sgi-ip27/ip27-irq.c | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 61817a18aed2..73e5e52781d8 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 5 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
6 | * Copyright (C) 1999 - 2001 Kanoj Sarcar | 6 | * Copyright (C) 1999 - 2001 Kanoj Sarcar |
7 | */ | 7 | */ |
8 | |||
9 | #undef DEBUG | ||
10 | |||
8 | #include <linux/config.h> | 11 | #include <linux/config.h> |
9 | #include <linux/init.h> | 12 | #include <linux/init.h> |
10 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
@@ -14,11 +17,11 @@ | |||
14 | #include <linux/types.h> | 17 | #include <linux/types.h> |
15 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
16 | #include <linux/ioport.h> | 19 | #include <linux/ioport.h> |
17 | #include <linux/irq.h> | ||
18 | #include <linux/timex.h> | 20 | #include <linux/timex.h> |
19 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
20 | #include <linux/random.h> | 22 | #include <linux/random.h> |
21 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
24 | #include <linux/kernel.h> | ||
22 | #include <linux/kernel_stat.h> | 25 | #include <linux/kernel_stat.h> |
23 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
24 | #include <linux/bitops.h> | 27 | #include <linux/bitops.h> |
@@ -37,13 +40,6 @@ | |||
37 | #include <asm/sn/hub.h> | 40 | #include <asm/sn/hub.h> |
38 | #include <asm/sn/intr.h> | 41 | #include <asm/sn/intr.h> |
39 | 42 | ||
40 | #undef DEBUG_IRQ | ||
41 | #ifdef DEBUG_IRQ | ||
42 | #define DBG(x...) printk(x) | ||
43 | #else | ||
44 | #define DBG(x...) | ||
45 | #endif | ||
46 | |||
47 | /* | 43 | /* |
48 | * Linux has a controller-independent x86 interrupt architecture. | 44 | * Linux has a controller-independent x86 interrupt architecture. |
49 | * every controller has a 'controller-template', that is used | 45 | * every controller has a 'controller-template', that is used |
@@ -74,14 +70,15 @@ extern int irq_to_slot[]; | |||
74 | 70 | ||
75 | static inline int alloc_level(int cpu, int irq) | 71 | static inline int alloc_level(int cpu, int irq) |
76 | { | 72 | { |
73 | struct hub_data *hub = hub_data(cpu_to_node(cpu)); | ||
77 | struct slice_data *si = cpu_data[cpu].data; | 74 | struct slice_data *si = cpu_data[cpu].data; |
78 | int level; /* pre-allocated entries */ | 75 | int level; |
79 | 76 | ||
80 | level = find_first_zero_bit(si->irq_alloc_mask, LEVELS_PER_SLICE); | 77 | level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE); |
81 | if (level >= LEVELS_PER_SLICE) | 78 | if (level >= LEVELS_PER_SLICE) |
82 | panic("Cpu %d flooded with devices\n", cpu); | 79 | panic("Cpu %d flooded with devices\n", cpu); |
83 | 80 | ||
84 | __set_bit(level, si->irq_alloc_mask); | 81 | __set_bit(level, hub->irq_alloc_mask); |
85 | si->level_to_irq[level] = irq; | 82 | si->level_to_irq[level] = irq; |
86 | 83 | ||
87 | return level; | 84 | return level; |
@@ -216,9 +213,11 @@ static int intr_connect_level(int cpu, int bit) | |||
216 | { | 213 | { |
217 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); | 214 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); |
218 | struct slice_data *si = cpu_data[cpu].data; | 215 | struct slice_data *si = cpu_data[cpu].data; |
216 | unsigned long flags; | ||
219 | 217 | ||
220 | __set_bit(bit, si->irq_enable_mask); | 218 | set_bit(bit, si->irq_enable_mask); |
221 | 219 | ||
220 | local_irq_save(flags); | ||
222 | if (!cputoslice(cpu)) { | 221 | if (!cputoslice(cpu)) { |
223 | REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); | 222 | REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); |
224 | REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); | 223 | REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); |
@@ -226,6 +225,7 @@ static int intr_connect_level(int cpu, int bit) | |||
226 | REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); | 225 | REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); |
227 | REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); | 226 | REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); |
228 | } | 227 | } |
228 | local_irq_restore(flags); | ||
229 | 229 | ||
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
@@ -235,7 +235,7 @@ static int intr_disconnect_level(int cpu, int bit) | |||
235 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); | 235 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); |
236 | struct slice_data *si = cpu_data[cpu].data; | 236 | struct slice_data *si = cpu_data[cpu].data; |
237 | 237 | ||
238 | __clear_bit(bit, si->irq_enable_mask); | 238 | clear_bit(bit, si->irq_enable_mask); |
239 | 239 | ||
240 | if (!cputoslice(cpu)) { | 240 | if (!cputoslice(cpu)) { |
241 | REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); | 241 | REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); |
@@ -261,7 +261,7 @@ static unsigned int startup_bridge_irq(unsigned int irq) | |||
261 | bc = IRQ_TO_BRIDGE(irq); | 261 | bc = IRQ_TO_BRIDGE(irq); |
262 | bridge = bc->base; | 262 | bridge = bc->base; |
263 | 263 | ||
264 | DBG("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); | 264 | pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); |
265 | /* | 265 | /* |
266 | * "map" irq to a swlevel greater than 6 since the first 6 bits | 266 | * "map" irq to a swlevel greater than 6 since the first 6 bits |
267 | * of INT_PEND0 are taken | 267 | * of INT_PEND0 are taken |
@@ -298,12 +298,13 @@ static unsigned int startup_bridge_irq(unsigned int irq) | |||
298 | static void shutdown_bridge_irq(unsigned int irq) | 298 | static void shutdown_bridge_irq(unsigned int irq) |
299 | { | 299 | { |
300 | struct bridge_controller *bc = IRQ_TO_BRIDGE(irq); | 300 | struct bridge_controller *bc = IRQ_TO_BRIDGE(irq); |
301 | struct hub_data *hub = hub_data(cpu_to_node(bc->irq_cpu)); | ||
301 | bridge_t *bridge = bc->base; | 302 | bridge_t *bridge = bc->base; |
302 | struct slice_data *si = cpu_data[bc->irq_cpu].data; | 303 | struct slice_data *si = cpu_data[bc->irq_cpu].data; |
303 | int pin, swlevel; | 304 | int pin, swlevel; |
304 | cpuid_t cpu; | 305 | cpuid_t cpu; |
305 | 306 | ||
306 | DBG("bridge_shutdown: irq 0x%x\n", irq); | 307 | pr_debug("bridge_shutdown: irq 0x%x\n", irq); |
307 | pin = SLOT_FROM_PCI_IRQ(irq); | 308 | pin = SLOT_FROM_PCI_IRQ(irq); |
308 | 309 | ||
309 | /* | 310 | /* |
@@ -313,7 +314,7 @@ static void shutdown_bridge_irq(unsigned int irq) | |||
313 | swlevel = find_level(&cpu, irq); | 314 | swlevel = find_level(&cpu, irq); |
314 | intr_disconnect_level(cpu, swlevel); | 315 | intr_disconnect_level(cpu, swlevel); |
315 | 316 | ||
316 | __clear_bit(swlevel, si->irq_alloc_mask); | 317 | __clear_bit(swlevel, hub->irq_alloc_mask); |
317 | si->level_to_irq[swlevel] = -1; | 318 | si->level_to_irq[swlevel] = -1; |
318 | 319 | ||
319 | bridge->b_int_enable &= ~(1 << pin); | 320 | bridge->b_int_enable &= ~(1 << pin); |
@@ -433,25 +434,24 @@ void install_ipi(void) | |||
433 | int slice = LOCAL_HUB_L(PI_CPU_NUM); | 434 | int slice = LOCAL_HUB_L(PI_CPU_NUM); |
434 | int cpu = smp_processor_id(); | 435 | int cpu = smp_processor_id(); |
435 | struct slice_data *si = cpu_data[cpu].data; | 436 | struct slice_data *si = cpu_data[cpu].data; |
436 | hubreg_t mask, set; | 437 | struct hub_data *hub = hub_data(cpu_to_node(cpu)); |
438 | int resched, call; | ||
439 | |||
440 | resched = CPU_RESCHED_A_IRQ + slice; | ||
441 | __set_bit(resched, hub->irq_alloc_mask); | ||
442 | __set_bit(resched, si->irq_enable_mask); | ||
443 | LOCAL_HUB_CLR_INTR(resched); | ||
444 | |||
445 | call = CPU_CALL_A_IRQ + slice; | ||
446 | __set_bit(call, hub->irq_alloc_mask); | ||
447 | __set_bit(call, si->irq_enable_mask); | ||
448 | LOCAL_HUB_CLR_INTR(call); | ||
437 | 449 | ||
438 | if (slice == 0) { | 450 | if (slice == 0) { |
439 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); | 451 | LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]); |
440 | LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); | 452 | LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]); |
441 | mask = LOCAL_HUB_L(PI_INT_MASK0_A); /* Slice A */ | ||
442 | set = (1UL << CPU_RESCHED_A_IRQ) | (1UL << CPU_CALL_A_IRQ); | ||
443 | mask |= set; | ||
444 | si->irq_enable_mask[0] |= set; | ||
445 | si->irq_alloc_mask[0] |= set; | ||
446 | LOCAL_HUB_S(PI_INT_MASK0_A, mask); | ||
447 | } else { | 453 | } else { |
448 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ); | 454 | LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]); |
449 | LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ); | 455 | LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]); |
450 | mask = LOCAL_HUB_L(PI_INT_MASK0_B); /* Slice B */ | ||
451 | set = (1UL << CPU_RESCHED_B_IRQ) | (1UL << CPU_CALL_B_IRQ); | ||
452 | mask |= set; | ||
453 | si->irq_enable_mask[1] |= set; | ||
454 | si->irq_alloc_mask[1] |= set; | ||
455 | LOCAL_HUB_S(PI_INT_MASK0_B, mask); | ||
456 | } | 456 | } |
457 | } | 457 | } |