ip27-irq.c revision 937a801576f954bd030d7c4a5a94571710d87c0b
1/* 2 * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. 3 * 4 * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) 5 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 6 * Copyright (C) 1999 - 2001 Kanoj Sarcar 7 */ 8 9#undef DEBUG 10 11#include <linux/init.h> 12#include <linux/irq.h> 13#include <linux/errno.h> 14#include <linux/signal.h> 15#include <linux/sched.h> 16#include <linux/types.h> 17#include <linux/interrupt.h> 18#include <linux/ioport.h> 19#include <linux/timex.h> 20#include <linux/slab.h> 21#include <linux/random.h> 22#include <linux/smp_lock.h> 23#include <linux/kernel.h> 24#include <linux/kernel_stat.h> 25#include <linux/delay.h> 26#include <linux/bitops.h> 27 28#include <asm/bootinfo.h> 29#include <asm/io.h> 30#include <asm/mipsregs.h> 31#include <asm/system.h> 32 33#include <asm/ptrace.h> 34#include <asm/processor.h> 35#include <asm/pci/bridge.h> 36#include <asm/sn/addrs.h> 37#include <asm/sn/agent.h> 38#include <asm/sn/arch.h> 39#include <asm/sn/hub.h> 40#include <asm/sn/intr.h> 41 42/* 43 * Linux has a controller-independent x86 interrupt architecture. 44 * every controller has a 'controller-template', that is used 45 * by the main code to do the right thing. Each driver-visible 46 * interrupt source is transparently wired to the apropriate 47 * controller. Thus drivers need not be aware of the 48 * interrupt-controller. 49 * 50 * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, 51 * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. 52 * (IO-APICs assumed to be messaging to Pentium local-APICs) 53 * 54 * the code is designed to be easily extended with new/different 55 * interrupt controllers, without having to do assembly magic. 56 */ 57 58extern asmlinkage void ip27_irq(void); 59 60extern struct bridge_controller *irq_to_bridge[]; 61extern int irq_to_slot[]; 62 63/* 64 * use these macros to get the encoded nasid and widget id 65 * from the irq value 66 */ 67#define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)] 68#define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i] 69 70static inline int alloc_level(int cpu, int irq) 71{ 72 struct hub_data *hub = hub_data(cpu_to_node(cpu)); 73 struct slice_data *si = cpu_data[cpu].data; 74 int level; 75 76 level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE); 77 if (level >= LEVELS_PER_SLICE) 78 panic("Cpu %d flooded with devices\n", cpu); 79 80 __set_bit(level, hub->irq_alloc_mask); 81 si->level_to_irq[level] = irq; 82 83 return level; 84} 85 86static inline int find_level(cpuid_t *cpunum, int irq) 87{ 88 int cpu, i; 89 90 for_each_online_cpu(cpu) { 91 struct slice_data *si = cpu_data[cpu].data; 92 93 for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++) 94 if (si->level_to_irq[i] == irq) { 95 *cpunum = cpu; 96 97 return i; 98 } 99 } 100 101 panic("Could not identify cpu/level for irq %d\n", irq); 102} 103 104/* 105 * Find first bit set 106 */ 107static int ms1bit(unsigned long x) 108{ 109 int b = 0, s; 110 111 s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s; 112 s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s; 113 s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s; 114 s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s; 115 s = 1; if (x >> 1 == 0) s = 0; b += s; 116 117 return b; 118} 119 120/* 121 * This code is unnecessarily complex, because we do IRQF_DISABLED 122 * intr enabling. Basically, once we grab the set of intrs we need 123 * to service, we must mask _all_ these interrupts; firstly, to make 124 * sure the same intr does not intr again, causing recursion that 125 * can lead to stack overflow. Secondly, we can not just mask the 126 * one intr we are do_IRQing, because the non-masked intrs in the 127 * first set might intr again, causing multiple servicings of the 128 * same intr. This effect is mostly seen for intercpu intrs. 129 * Kanoj 05.13.00 130 */ 131 132static void ip27_do_irq_mask0(void) 133{ 134 int irq, swlevel; 135 hubreg_t pend0, mask0; 136 cpuid_t cpu = smp_processor_id(); 137 int pi_int_mask0 = 138 (cputoslice(cpu) == 0) ? PI_INT_MASK0_A : PI_INT_MASK0_B; 139 140 /* copied from Irix intpend0() */ 141 pend0 = LOCAL_HUB_L(PI_INT_PEND0); 142 mask0 = LOCAL_HUB_L(pi_int_mask0); 143 144 pend0 &= mask0; /* Pick intrs we should look at */ 145 if (!pend0) 146 return; 147 148 swlevel = ms1bit(pend0); 149#ifdef CONFIG_SMP 150 if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { 151 LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); 152 } else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) { 153 LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ); 154 } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { 155 LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); 156 smp_call_function_interrupt(); 157 } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) { 158 LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ); 159 smp_call_function_interrupt(); 160 } else 161#endif 162 { 163 /* "map" swlevel to irq */ 164 struct slice_data *si = cpu_data[cpu].data; 165 166 irq = si->level_to_irq[swlevel]; 167 do_IRQ(irq); 168 } 169 170 LOCAL_HUB_L(PI_INT_PEND0); 171} 172 173static void ip27_do_irq_mask1(void) 174{ 175 int irq, swlevel; 176 hubreg_t pend1, mask1; 177 cpuid_t cpu = smp_processor_id(); 178 int pi_int_mask1 = (cputoslice(cpu) == 0) ? PI_INT_MASK1_A : PI_INT_MASK1_B; 179 struct slice_data *si = cpu_data[cpu].data; 180 181 /* copied from Irix intpend0() */ 182 pend1 = LOCAL_HUB_L(PI_INT_PEND1); 183 mask1 = LOCAL_HUB_L(pi_int_mask1); 184 185 pend1 &= mask1; /* Pick intrs we should look at */ 186 if (!pend1) 187 return; 188 189 swlevel = ms1bit(pend1); 190 /* "map" swlevel to irq */ 191 irq = si->level_to_irq[swlevel]; 192 LOCAL_HUB_CLR_INTR(swlevel); 193 do_IRQ(irq); 194 195 LOCAL_HUB_L(PI_INT_PEND1); 196} 197 198static void ip27_prof_timer(void) 199{ 200 panic("CPU %d got a profiling interrupt", smp_processor_id()); 201} 202 203static void ip27_hub_error(void) 204{ 205 panic("CPU %d got a hub error interrupt", smp_processor_id()); 206} 207 208static int intr_connect_level(int cpu, int bit) 209{ 210 nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); 211 struct slice_data *si = cpu_data[cpu].data; 212 unsigned long flags; 213 214 set_bit(bit, si->irq_enable_mask); 215 216 local_irq_save(flags); 217 if (!cputoslice(cpu)) { 218 REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); 219 REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); 220 } else { 221 REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); 222 REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); 223 } 224 local_irq_restore(flags); 225 226 return 0; 227} 228 229static int intr_disconnect_level(int cpu, int bit) 230{ 231 nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); 232 struct slice_data *si = cpu_data[cpu].data; 233 234 clear_bit(bit, si->irq_enable_mask); 235 236 if (!cputoslice(cpu)) { 237 REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); 238 REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); 239 } else { 240 REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); 241 REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); 242 } 243 244 return 0; 245} 246 247/* Startup one of the (PCI ...) IRQs routes over a bridge. */ 248static unsigned int startup_bridge_irq(unsigned int irq) 249{ 250 struct bridge_controller *bc; 251 bridgereg_t device; 252 bridge_t *bridge; 253 int pin, swlevel; 254 cpuid_t cpu; 255 256 pin = SLOT_FROM_PCI_IRQ(irq); 257 bc = IRQ_TO_BRIDGE(irq); 258 bridge = bc->base; 259 260 pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", irq, pin); 261 /* 262 * "map" irq to a swlevel greater than 6 since the first 6 bits 263 * of INT_PEND0 are taken 264 */ 265 swlevel = find_level(&cpu, irq); 266 bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); 267 bridge->b_int_enable |= (1 << pin); 268 bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ 269 270 /* 271 * Enable sending of an interrupt clear packt to the hub on a high to 272 * low transition of the interrupt pin. 273 * 274 * IRIX sets additional bits in the address which are documented as 275 * reserved in the bridge docs. 276 */ 277 bridge->b_int_mode |= (1UL << pin); 278 279 /* 280 * We assume the bridge to have a 1:1 mapping between devices 281 * (slots) and intr pins. 282 */ 283 device = bridge->b_int_device; 284 device &= ~(7 << (pin*3)); 285 device |= (pin << (pin*3)); 286 bridge->b_int_device = device; 287 288 bridge->b_wid_tflush; 289 290 return 0; /* Never anything pending. */ 291} 292 293/* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ 294static void shutdown_bridge_irq(unsigned int irq) 295{ 296 struct bridge_controller *bc = IRQ_TO_BRIDGE(irq); 297 struct hub_data *hub = hub_data(cpu_to_node(bc->irq_cpu)); 298 bridge_t *bridge = bc->base; 299 int pin, swlevel; 300 cpuid_t cpu; 301 302 pr_debug("bridge_shutdown: irq 0x%x\n", irq); 303 pin = SLOT_FROM_PCI_IRQ(irq); 304 305 /* 306 * map irq to a swlevel greater than 6 since the first 6 bits 307 * of INT_PEND0 are taken 308 */ 309 swlevel = find_level(&cpu, irq); 310 intr_disconnect_level(cpu, swlevel); 311 312 __clear_bit(swlevel, hub->irq_alloc_mask); 313 314 bridge->b_int_enable &= ~(1 << pin); 315 bridge->b_wid_tflush; 316} 317 318static inline void enable_bridge_irq(unsigned int irq) 319{ 320 cpuid_t cpu; 321 int swlevel; 322 323 swlevel = find_level(&cpu, irq); /* Criminal offence */ 324 intr_connect_level(cpu, swlevel); 325} 326 327static inline void disable_bridge_irq(unsigned int irq) 328{ 329 cpuid_t cpu; 330 int swlevel; 331 332 swlevel = find_level(&cpu, irq); /* Criminal offence */ 333 intr_disconnect_level(cpu, swlevel); 334} 335 336static void mask_and_ack_bridge_irq(unsigned int irq) 337{ 338 disable_bridge_irq(irq); 339} 340 341static void end_bridge_irq(unsigned int irq) 342{ 343 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && 344 irq_desc[irq].action) 345 enable_bridge_irq(irq); 346} 347 348static struct irq_chip bridge_irq_type = { 349 .typename = "bridge", 350 .startup = startup_bridge_irq, 351 .shutdown = shutdown_bridge_irq, 352 .enable = enable_bridge_irq, 353 .disable = disable_bridge_irq, 354 .ack = mask_and_ack_bridge_irq, 355 .end = end_bridge_irq, 356}; 357 358static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; 359 360int allocate_irqno(void) 361{ 362 int irq; 363 364again: 365 irq = find_first_zero_bit(irq_map, NR_IRQS); 366 367 if (irq >= NR_IRQS) 368 return -ENOSPC; 369 370 if (test_and_set_bit(irq, irq_map)) 371 goto again; 372 373 return irq; 374} 375 376void free_irqno(unsigned int irq) 377{ 378 clear_bit(irq, irq_map); 379} 380 381void __devinit register_bridge_irq(unsigned int irq) 382{ 383 irq_desc[irq].status = IRQ_DISABLED; 384 irq_desc[irq].action = 0; 385 irq_desc[irq].depth = 1; 386 irq_desc[irq].chip = &bridge_irq_type; 387} 388 389int __devinit request_bridge_irq(struct bridge_controller *bc) 390{ 391 int irq = allocate_irqno(); 392 int swlevel, cpu; 393 nasid_t nasid; 394 395 if (irq < 0) 396 return irq; 397 398 /* 399 * "map" irq to a swlevel greater than 6 since the first 6 bits 400 * of INT_PEND0 are taken 401 */ 402 cpu = bc->irq_cpu; 403 swlevel = alloc_level(cpu, irq); 404 if (unlikely(swlevel < 0)) { 405 free_irqno(irq); 406 407 return -EAGAIN; 408 } 409 410 /* Make sure it's not already pending when we connect it. */ 411 nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); 412 REMOTE_HUB_CLR_INTR(nasid, swlevel); 413 414 intr_connect_level(cpu, swlevel); 415 416 register_bridge_irq(irq); 417 418 return irq; 419} 420 421extern void ip27_rt_timer_interrupt(void); 422 423asmlinkage void plat_irq_dispatch(void) 424{ 425 unsigned long pending = read_c0_cause() & read_c0_status(); 426 427 if (pending & CAUSEF_IP4) 428 ip27_rt_timer_interrupt(); 429 else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ 430 ip27_do_irq_mask0(); 431 else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ 432 ip27_do_irq_mask1(); 433 else if (pending & CAUSEF_IP5) 434 ip27_prof_timer(); 435 else if (pending & CAUSEF_IP6) 436 ip27_hub_error(); 437} 438 439void __init arch_init_irq(void) 440{ 441} 442 443void install_ipi(void) 444{ 445 int slice = LOCAL_HUB_L(PI_CPU_NUM); 446 int cpu = smp_processor_id(); 447 struct slice_data *si = cpu_data[cpu].data; 448 struct hub_data *hub = hub_data(cpu_to_node(cpu)); 449 int resched, call; 450 451 resched = CPU_RESCHED_A_IRQ + slice; 452 __set_bit(resched, hub->irq_alloc_mask); 453 __set_bit(resched, si->irq_enable_mask); 454 LOCAL_HUB_CLR_INTR(resched); 455 456 call = CPU_CALL_A_IRQ + slice; 457 __set_bit(call, hub->irq_alloc_mask); 458 __set_bit(call, si->irq_enable_mask); 459 LOCAL_HUB_CLR_INTR(call); 460 461 if (slice == 0) { 462 LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]); 463 LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]); 464 } else { 465 LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]); 466 LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]); 467 } 468} 469