diff options
-rw-r--r-- | arch/sparc64/kernel/devices.c | 2 | ||||
-rw-r--r-- | arch/sparc64/kernel/irq.c | 70 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_psycho.c | 77 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sabre.c | 81 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_schizo.c | 104 | ||||
-rw-r--r-- | arch/sparc64/kernel/pci_sun4v.c | 32 | ||||
-rw-r--r-- | arch/sparc64/kernel/sbus.c | 47 | ||||
-rw-r--r-- | include/asm-sparc64/irq.h | 11 |
8 files changed, 43 insertions, 381 deletions
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index 007e8922cd16..0684899d998b 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c | |||
@@ -157,7 +157,7 @@ unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node) | |||
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
159 | 159 | ||
160 | return sun4v_build_irq(sun4v_vdev_devhandle, irq, 5, 0); | 160 | return sun4v_build_irq(sun4v_vdev_devhandle, irq, 0); |
161 | } | 161 | } |
162 | 162 | ||
163 | static const char *cpu_mid_prop(void) | 163 | static const char *cpu_mid_prop(void) |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index ad134bbc151c..f2668f2bed9c 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -70,7 +70,7 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY | |||
70 | */ | 70 | */ |
71 | #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) | 71 | #define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) |
72 | 72 | ||
73 | static struct irqaction *irq_action[NR_IRQS+1]; | 73 | static struct irqaction *irq_action[NR_IRQS]; |
74 | 74 | ||
75 | /* This only synchronizes entities which modify IRQ handler | 75 | /* This only synchronizes entities which modify IRQ handler |
76 | * state and some selected user-level spots that want to | 76 | * state and some selected user-level spots that want to |
@@ -116,12 +116,9 @@ int show_interrupts(struct seq_file *p, void *v) | |||
116 | kstat_cpu(j).irqs[i]); | 116 | kstat_cpu(j).irqs[i]); |
117 | } | 117 | } |
118 | #endif | 118 | #endif |
119 | seq_printf(p, " %s:%lx", action->name, | 119 | seq_printf(p, " %s", action->name); |
120 | get_ino_in_irqaction(action)); | 120 | for (action = action->next; action; action = action->next) |
121 | for (action = action->next; action; action = action->next) { | 121 | seq_printf(p, ", %s", action->name); |
122 | seq_printf(p, ", %s:%lx", action->name, | ||
123 | get_ino_in_irqaction(action)); | ||
124 | } | ||
125 | seq_putc(p, '\n'); | 122 | seq_putc(p, '\n'); |
126 | } | 123 | } |
127 | out_unlock: | 124 | out_unlock: |
@@ -245,48 +242,47 @@ void disable_irq(unsigned int irq) | |||
245 | } | 242 | } |
246 | } | 243 | } |
247 | 244 | ||
248 | static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, | 245 | static void build_irq_error(const char *msg, unsigned int ino, int inofixup, |
249 | unsigned long iclr, unsigned long imap, | 246 | unsigned long iclr, unsigned long imap, |
250 | struct ino_bucket *bucket) | 247 | struct ino_bucket *bucket) |
251 | { | 248 | { |
252 | prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> " | 249 | prom_printf("IRQ: INO %04x (%016lx:%016lx) --> " |
253 | "(%d:%d:%016lx:%016lx), halting...\n", | 250 | "(%d:%016lx:%016lx), halting...\n", |
254 | ino, bucket->pil, bucket->iclr, bucket->imap, | 251 | ino, bucket->iclr, bucket->imap, |
255 | pil, inofixup, iclr, imap); | 252 | inofixup, iclr, imap); |
256 | prom_halt(); | 253 | prom_halt(); |
257 | } | 254 | } |
258 | 255 | ||
259 | unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) | 256 | unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) |
260 | { | 257 | { |
261 | struct ino_bucket *bucket; | 258 | struct ino_bucket *bucket; |
262 | int ino; | 259 | int ino; |
263 | 260 | ||
264 | BUG_ON(pil == 0); | ||
265 | BUG_ON(tlb_type == hypervisor); | 261 | BUG_ON(tlb_type == hypervisor); |
266 | 262 | ||
267 | /* RULE: Both must be specified in all other cases. */ | 263 | /* RULE: Both must be specified in all other cases. */ |
268 | if (iclr == 0UL || imap == 0UL) { | 264 | if (iclr == 0UL || imap == 0UL) { |
269 | prom_printf("Invalid build_irq %d %d %016lx %016lx\n", | 265 | prom_printf("Invalid build_irq %d %016lx %016lx\n", |
270 | pil, inofixup, iclr, imap); | 266 | inofixup, iclr, imap); |
271 | prom_halt(); | 267 | prom_halt(); |
272 | } | 268 | } |
273 | 269 | ||
274 | ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; | 270 | ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; |
275 | if (ino > NUM_IVECS) { | 271 | if (ino > NUM_IVECS) { |
276 | prom_printf("Invalid INO %04x (%d:%d:%016lx:%016lx)\n", | 272 | prom_printf("Invalid INO %04x (%d:%016lx:%016lx)\n", |
277 | ino, pil, inofixup, iclr, imap); | 273 | ino, inofixup, iclr, imap); |
278 | prom_halt(); | 274 | prom_halt(); |
279 | } | 275 | } |
280 | 276 | ||
281 | bucket = &ivector_table[ino]; | 277 | bucket = &ivector_table[ino]; |
282 | if (bucket->flags & IBF_ACTIVE) | 278 | if (bucket->flags & IBF_ACTIVE) |
283 | build_irq_error("IRQ: Trying to build active INO bucket.\n", | 279 | build_irq_error("IRQ: Trying to build active INO bucket.\n", |
284 | ino, pil, inofixup, iclr, imap, bucket); | 280 | ino, inofixup, iclr, imap, bucket); |
285 | 281 | ||
286 | if (bucket->irq_info) { | 282 | if (bucket->irq_info) { |
287 | if (bucket->imap != imap || bucket->iclr != iclr) | 283 | if (bucket->imap != imap || bucket->iclr != iclr) |
288 | build_irq_error("IRQ: Trying to reinit INO bucket.\n", | 284 | build_irq_error("IRQ: Trying to reinit INO bucket.\n", |
289 | ino, pil, inofixup, iclr, imap, bucket); | 285 | ino, inofixup, iclr, imap, bucket); |
290 | 286 | ||
291 | goto out; | 287 | goto out; |
292 | } | 288 | } |
@@ -302,14 +298,13 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long | |||
302 | */ | 298 | */ |
303 | bucket->imap = imap; | 299 | bucket->imap = imap; |
304 | bucket->iclr = iclr; | 300 | bucket->iclr = iclr; |
305 | bucket->pil = pil; | ||
306 | bucket->flags = 0; | 301 | bucket->flags = 0; |
307 | 302 | ||
308 | out: | 303 | out: |
309 | return __irq(bucket); | 304 | return __irq(bucket); |
310 | } | 305 | } |
311 | 306 | ||
312 | unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags) | 307 | unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags) |
313 | { | 308 | { |
314 | struct ino_bucket *bucket; | 309 | struct ino_bucket *bucket; |
315 | unsigned long sysino; | 310 | unsigned long sysino; |
@@ -328,7 +323,6 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsign | |||
328 | bucket->imap = ~0UL - sysino; | 323 | bucket->imap = ~0UL - sysino; |
329 | bucket->iclr = ~0UL - sysino; | 324 | bucket->iclr = ~0UL - sysino; |
330 | 325 | ||
331 | bucket->pil = pil; | ||
332 | bucket->flags = flags; | 326 | bucket->flags = flags; |
333 | 327 | ||
334 | bucket->irq_info = kzalloc(sizeof(struct irq_desc), GFP_ATOMIC); | 328 | bucket->irq_info = kzalloc(sizeof(struct irq_desc), GFP_ATOMIC); |
@@ -356,16 +350,12 @@ static void atomic_bucket_insert(struct ino_bucket *bucket) | |||
356 | 350 | ||
357 | static int check_irq_sharing(int pil, unsigned long irqflags) | 351 | static int check_irq_sharing(int pil, unsigned long irqflags) |
358 | { | 352 | { |
359 | struct irqaction *action, *tmp; | 353 | struct irqaction *action; |
360 | 354 | ||
361 | action = *(irq_action + pil); | 355 | action = *(irq_action + pil); |
362 | if (action) { | 356 | if (action) { |
363 | if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { | 357 | if (!(action->flags & SA_SHIRQ) || !(irqflags & SA_SHIRQ)) |
364 | for (tmp = action; tmp->next; tmp = tmp->next) | ||
365 | ; | ||
366 | } else { | ||
367 | return -EBUSY; | 358 | return -EBUSY; |
368 | } | ||
369 | } | 359 | } |
370 | return 0; | 360 | return 0; |
371 | } | 361 | } |
@@ -425,12 +415,12 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ | |||
425 | * installing a new handler, but is this really a problem, | 415 | * installing a new handler, but is this really a problem, |
426 | * only the sysadmin is able to do this. | 416 | * only the sysadmin is able to do this. |
427 | */ | 417 | */ |
428 | rand_initialize_irq(irq); | 418 | rand_initialize_irq(PIL_DEVICE_IRQ); |
429 | } | 419 | } |
430 | 420 | ||
431 | spin_lock_irqsave(&irq_action_lock, flags); | 421 | spin_lock_irqsave(&irq_action_lock, flags); |
432 | 422 | ||
433 | if (check_irq_sharing(bucket->pil, irqflags)) { | 423 | if (check_irq_sharing(PIL_DEVICE_IRQ, irqflags)) { |
434 | spin_unlock_irqrestore(&irq_action_lock, flags); | 424 | spin_unlock_irqrestore(&irq_action_lock, flags); |
435 | return -EBUSY; | 425 | return -EBUSY; |
436 | } | 426 | } |
@@ -454,7 +444,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ | |||
454 | put_ino_in_irqaction(action, irq); | 444 | put_ino_in_irqaction(action, irq); |
455 | put_smpaff_in_irqaction(action, CPU_MASK_NONE); | 445 | put_smpaff_in_irqaction(action, CPU_MASK_NONE); |
456 | 446 | ||
457 | append_irq_action(bucket->pil, action); | 447 | append_irq_action(PIL_DEVICE_IRQ, action); |
458 | 448 | ||
459 | enable_irq(irq); | 449 | enable_irq(irq); |
460 | 450 | ||
@@ -478,16 +468,15 @@ EXPORT_SYMBOL(request_irq); | |||
478 | 468 | ||
479 | static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) | 469 | static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) |
480 | { | 470 | { |
481 | struct ino_bucket *bucket = __bucket(irq); | ||
482 | struct irqaction *action, **pp; | 471 | struct irqaction *action, **pp; |
483 | 472 | ||
484 | pp = irq_action + bucket->pil; | 473 | pp = irq_action + PIL_DEVICE_IRQ; |
485 | action = *pp; | 474 | action = *pp; |
486 | if (unlikely(!action)) | 475 | if (unlikely(!action)) |
487 | return NULL; | 476 | return NULL; |
488 | 477 | ||
489 | if (unlikely(!action->handler)) { | 478 | if (unlikely(!action->handler)) { |
490 | printk("Freeing free IRQ %d\n", bucket->pil); | 479 | printk("Freeing free IRQ %d\n", PIL_DEVICE_IRQ); |
491 | return NULL; | 480 | return NULL; |
492 | } | 481 | } |
493 | 482 | ||
@@ -648,7 +637,7 @@ static void process_bucket(struct ino_bucket *bp, struct pt_regs *regs) | |||
648 | 637 | ||
649 | /* Test and add entropy */ | 638 | /* Test and add entropy */ |
650 | if (random & SA_SAMPLE_RANDOM) | 639 | if (random & SA_SAMPLE_RANDOM) |
651 | add_interrupt_randomness(bp->pil); | 640 | add_interrupt_randomness(PIL_DEVICE_IRQ); |
652 | out: | 641 | out: |
653 | bp->flags &= ~IBF_INPROGRESS; | 642 | bp->flags &= ~IBF_INPROGRESS; |
654 | } | 643 | } |
@@ -691,7 +680,7 @@ void handler_irq(int irq, struct pt_regs *regs) | |||
691 | while (bp) { | 680 | while (bp) { |
692 | struct ino_bucket *nbp = __bucket(bp->irq_chain); | 681 | struct ino_bucket *nbp = __bucket(bp->irq_chain); |
693 | 682 | ||
694 | kstat_this_cpu.irqs[bp->pil]++; | 683 | kstat_this_cpu.irqs[bp->virt_irq]++; |
695 | 684 | ||
696 | bp->irq_chain = 0; | 685 | bp->irq_chain = 0; |
697 | process_bucket(bp, regs); | 686 | process_bucket(bp, regs); |
@@ -817,16 +806,9 @@ static void distribute_irqs(void) | |||
817 | spin_lock_irqsave(&irq_action_lock, flags); | 806 | spin_lock_irqsave(&irq_action_lock, flags); |
818 | cpu = 0; | 807 | cpu = 0; |
819 | 808 | ||
820 | /* | ||
821 | * Skip the timer at [0], and very rare error/power intrs at [15]. | ||
822 | * Also level [12], it causes problems on Ex000 systems. | ||
823 | */ | ||
824 | for (level = 1; level < NR_IRQS; level++) { | 809 | for (level = 1; level < NR_IRQS; level++) { |
825 | struct irqaction *p = irq_action[level]; | 810 | struct irqaction *p = irq_action[level]; |
826 | 811 | ||
827 | if (level == 12) | ||
828 | continue; | ||
829 | |||
830 | while(p) { | 812 | while(p) { |
831 | cpu = retarget_one_irq(p, cpu); | 813 | cpu = retarget_one_irq(p, cpu); |
832 | p = p->next; | 814 | p = p->next; |
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index d17878b145c2..5743e1316a93 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c | |||
@@ -276,74 +276,6 @@ static unsigned long __onboard_imap_off[] = { | |||
276 | ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ | 276 | ((ino & 0x20) ? (PSYCHO_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ |
277 | (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) | 277 | (PSYCHO_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) |
278 | 278 | ||
279 | /* PCI PSYCHO INO number to Sparc PIL level. */ | ||
280 | static unsigned char psycho_pil_table[] = { | ||
281 | /*0x00*/0, 0, 0, 0, /* PCI A slot 0 Int A, B, C, D */ | ||
282 | /*0x04*/0, 0, 0, 0, /* PCI A slot 1 Int A, B, C, D */ | ||
283 | /*0x08*/0, 0, 0, 0, /* PCI A slot 2 Int A, B, C, D */ | ||
284 | /*0x0c*/0, 0, 0, 0, /* PCI A slot 3 Int A, B, C, D */ | ||
285 | /*0x10*/0, 0, 0, 0, /* PCI B slot 0 Int A, B, C, D */ | ||
286 | /*0x14*/0, 0, 0, 0, /* PCI B slot 1 Int A, B, C, D */ | ||
287 | /*0x18*/0, 0, 0, 0, /* PCI B slot 2 Int A, B, C, D */ | ||
288 | /*0x1c*/0, 0, 0, 0, /* PCI B slot 3 Int A, B, C, D */ | ||
289 | /*0x20*/5, /* SCSI */ | ||
290 | /*0x21*/5, /* Ethernet */ | ||
291 | /*0x22*/8, /* Parallel Port */ | ||
292 | /*0x23*/13, /* Audio Record */ | ||
293 | /*0x24*/14, /* Audio Playback */ | ||
294 | /*0x25*/15, /* PowerFail */ | ||
295 | /*0x26*/5, /* second SCSI */ | ||
296 | /*0x27*/11, /* Floppy */ | ||
297 | /*0x28*/5, /* Spare Hardware */ | ||
298 | /*0x29*/9, /* Keyboard */ | ||
299 | /*0x2a*/5, /* Mouse */ | ||
300 | /*0x2b*/12, /* Serial */ | ||
301 | /*0x2c*/10, /* Timer 0 */ | ||
302 | /*0x2d*/11, /* Timer 1 */ | ||
303 | /*0x2e*/15, /* Uncorrectable ECC */ | ||
304 | /*0x2f*/15, /* Correctable ECC */ | ||
305 | /*0x30*/15, /* PCI Bus A Error */ | ||
306 | /*0x31*/15, /* PCI Bus B Error */ | ||
307 | /*0x32*/15, /* Power Management */ | ||
308 | }; | ||
309 | |||
310 | static int psycho_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | ||
311 | { | ||
312 | int ret; | ||
313 | |||
314 | ret = psycho_pil_table[ino]; | ||
315 | if (ret == 0 && pdev == NULL) { | ||
316 | ret = 5; | ||
317 | } else if (ret == 0) { | ||
318 | switch ((pdev->class >> 16) & 0xff) { | ||
319 | case PCI_BASE_CLASS_STORAGE: | ||
320 | ret = 5; | ||
321 | break; | ||
322 | |||
323 | case PCI_BASE_CLASS_NETWORK: | ||
324 | ret = 6; | ||
325 | break; | ||
326 | |||
327 | case PCI_BASE_CLASS_DISPLAY: | ||
328 | ret = 9; | ||
329 | break; | ||
330 | |||
331 | case PCI_BASE_CLASS_MULTIMEDIA: | ||
332 | case PCI_BASE_CLASS_MEMORY: | ||
333 | case PCI_BASE_CLASS_BRIDGE: | ||
334 | case PCI_BASE_CLASS_SERIAL: | ||
335 | ret = 10; | ||
336 | break; | ||
337 | |||
338 | default: | ||
339 | ret = 5; | ||
340 | break; | ||
341 | }; | ||
342 | } | ||
343 | |||
344 | return ret; | ||
345 | } | ||
346 | |||
347 | static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, | 279 | static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, |
348 | struct pci_dev *pdev, | 280 | struct pci_dev *pdev, |
349 | unsigned int ino) | 281 | unsigned int ino) |
@@ -351,7 +283,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, | |||
351 | struct ino_bucket *bucket; | 283 | struct ino_bucket *bucket; |
352 | unsigned long imap, iclr; | 284 | unsigned long imap, iclr; |
353 | unsigned long imap_off, iclr_off; | 285 | unsigned long imap_off, iclr_off; |
354 | int pil, inofixup = 0; | 286 | int inofixup = 0; |
355 | 287 | ||
356 | ino &= PCI_IRQ_INO; | 288 | ino &= PCI_IRQ_INO; |
357 | if (ino < PSYCHO_ONBOARD_IRQ_BASE) { | 289 | if (ino < PSYCHO_ONBOARD_IRQ_BASE) { |
@@ -367,11 +299,6 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, | |||
367 | } | 299 | } |
368 | 300 | ||
369 | /* Now build the IRQ bucket. */ | 301 | /* Now build the IRQ bucket. */ |
370 | pil = psycho_ino_to_pil(pdev, ino); | ||
371 | |||
372 | if (PIL_RESERVED(pil)) | ||
373 | BUG(); | ||
374 | |||
375 | imap = pbm->controller_regs + imap_off; | 302 | imap = pbm->controller_regs + imap_off; |
376 | imap += 4; | 303 | imap += 4; |
377 | 304 | ||
@@ -382,7 +309,7 @@ static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, | |||
382 | if ((ino & 0x20) == 0) | 309 | if ((ino & 0x20) == 0) |
383 | inofixup = ino & 0x03; | 310 | inofixup = ino & 0x03; |
384 | 311 | ||
385 | bucket = __bucket(build_irq(pil, inofixup, iclr, imap)); | 312 | bucket = __bucket(build_irq(inofixup, iclr, imap)); |
386 | bucket->flags |= IBF_PCI; | 313 | bucket->flags |= IBF_PCI; |
387 | 314 | ||
388 | return __irq(bucket); | 315 | return __irq(bucket); |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index f67bb7f078cf..caa7aeed5d14 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -523,78 +523,6 @@ static unsigned long __onboard_imap_off[] = { | |||
523 | ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ | 523 | ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) : \ |
524 | (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) | 524 | (SABRE_ICLR_A_SLOT0 + (((ino) & 0x1f)<<3))) |
525 | 525 | ||
526 | /* PCI SABRE INO number to Sparc PIL level. */ | ||
527 | static unsigned char sabre_pil_table[] = { | ||
528 | /*0x00*/0, 0, 0, 0, /* PCI A slot 0 Int A, B, C, D */ | ||
529 | /*0x04*/0, 0, 0, 0, /* PCI A slot 1 Int A, B, C, D */ | ||
530 | /*0x08*/0, 0, 0, 0, /* PCI A slot 2 Int A, B, C, D */ | ||
531 | /*0x0c*/0, 0, 0, 0, /* PCI A slot 3 Int A, B, C, D */ | ||
532 | /*0x10*/0, 0, 0, 0, /* PCI B slot 0 Int A, B, C, D */ | ||
533 | /*0x14*/0, 0, 0, 0, /* PCI B slot 1 Int A, B, C, D */ | ||
534 | /*0x18*/0, 0, 0, 0, /* PCI B slot 2 Int A, B, C, D */ | ||
535 | /*0x1c*/0, 0, 0, 0, /* PCI B slot 3 Int A, B, C, D */ | ||
536 | /*0x20*/5, /* SCSI */ | ||
537 | /*0x21*/5, /* Ethernet */ | ||
538 | /*0x22*/8, /* Parallel Port */ | ||
539 | /*0x23*/13, /* Audio Record */ | ||
540 | /*0x24*/14, /* Audio Playback */ | ||
541 | /*0x25*/15, /* PowerFail */ | ||
542 | /*0x26*/5, /* second SCSI */ | ||
543 | /*0x27*/11, /* Floppy */ | ||
544 | /*0x28*/5, /* Spare Hardware */ | ||
545 | /*0x29*/9, /* Keyboard */ | ||
546 | /*0x2a*/5, /* Mouse */ | ||
547 | /*0x2b*/12, /* Serial */ | ||
548 | /*0x2c*/10, /* Timer 0 */ | ||
549 | /*0x2d*/11, /* Timer 1 */ | ||
550 | /*0x2e*/15, /* Uncorrectable ECC */ | ||
551 | /*0x2f*/15, /* Correctable ECC */ | ||
552 | /*0x30*/15, /* PCI Bus A Error */ | ||
553 | /*0x31*/15, /* PCI Bus B Error */ | ||
554 | /*0x32*/15, /* Power Management */ | ||
555 | }; | ||
556 | |||
557 | static int sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | ||
558 | { | ||
559 | int ret; | ||
560 | |||
561 | if (pdev && | ||
562 | pdev->vendor == PCI_VENDOR_ID_SUN && | ||
563 | pdev->device == PCI_DEVICE_ID_SUN_RIO_USB) | ||
564 | return 9; | ||
565 | |||
566 | ret = sabre_pil_table[ino]; | ||
567 | if (ret == 0 && pdev == NULL) { | ||
568 | ret = 5; | ||
569 | } else if (ret == 0) { | ||
570 | switch ((pdev->class >> 16) & 0xff) { | ||
571 | case PCI_BASE_CLASS_STORAGE: | ||
572 | ret = 5; | ||
573 | break; | ||
574 | |||
575 | case PCI_BASE_CLASS_NETWORK: | ||
576 | ret = 6; | ||
577 | break; | ||
578 | |||
579 | case PCI_BASE_CLASS_DISPLAY: | ||
580 | ret = 9; | ||
581 | break; | ||
582 | |||
583 | case PCI_BASE_CLASS_MULTIMEDIA: | ||
584 | case PCI_BASE_CLASS_MEMORY: | ||
585 | case PCI_BASE_CLASS_BRIDGE: | ||
586 | case PCI_BASE_CLASS_SERIAL: | ||
587 | ret = 10; | ||
588 | break; | ||
589 | |||
590 | default: | ||
591 | ret = 5; | ||
592 | break; | ||
593 | }; | ||
594 | } | ||
595 | return ret; | ||
596 | } | ||
597 | |||
598 | /* When a device lives behind a bridge deeper in the PCI bus topology | 526 | /* When a device lives behind a bridge deeper in the PCI bus topology |
599 | * than APB, a special sequence must run to make sure all pending DMA | 527 | * than APB, a special sequence must run to make sure all pending DMA |
600 | * transfers at the time of IRQ delivery are visible in the coherency | 528 | * transfers at the time of IRQ delivery are visible in the coherency |
@@ -619,7 +547,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, | |||
619 | struct ino_bucket *bucket; | 547 | struct ino_bucket *bucket; |
620 | unsigned long imap, iclr; | 548 | unsigned long imap, iclr; |
621 | unsigned long imap_off, iclr_off; | 549 | unsigned long imap_off, iclr_off; |
622 | int pil, inofixup = 0; | 550 | int inofixup = 0; |
623 | 551 | ||
624 | ino &= PCI_IRQ_INO; | 552 | ino &= PCI_IRQ_INO; |
625 | if (ino < SABRE_ONBOARD_IRQ_BASE) { | 553 | if (ino < SABRE_ONBOARD_IRQ_BASE) { |
@@ -635,11 +563,6 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, | |||
635 | } | 563 | } |
636 | 564 | ||
637 | /* Now build the IRQ bucket. */ | 565 | /* Now build the IRQ bucket. */ |
638 | pil = sabre_ino_to_pil(pdev, ino); | ||
639 | |||
640 | if (PIL_RESERVED(pil)) | ||
641 | BUG(); | ||
642 | |||
643 | imap = pbm->controller_regs + imap_off; | 566 | imap = pbm->controller_regs + imap_off; |
644 | imap += 4; | 567 | imap += 4; |
645 | 568 | ||
@@ -650,7 +573,7 @@ static unsigned int sabre_irq_build(struct pci_pbm_info *pbm, | |||
650 | if ((ino & 0x20) == 0) | 573 | if ((ino & 0x20) == 0) |
651 | inofixup = ino & 0x03; | 574 | inofixup = ino & 0x03; |
652 | 575 | ||
653 | bucket = __bucket(build_irq(pil, inofixup, iclr, imap)); | 576 | bucket = __bucket(build_irq(inofixup, iclr, imap)); |
654 | bucket->flags |= IBF_PCI; | 577 | bucket->flags |= IBF_PCI; |
655 | 578 | ||
656 | if (pdev) { | 579 | if (pdev) { |
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 7fe4de03ac2e..ca49ef08236d 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c | |||
@@ -232,101 +232,6 @@ static unsigned long schizo_iclr_offset(unsigned long ino) | |||
232 | return SCHIZO_ICLR_BASE + (ino * 8UL); | 232 | return SCHIZO_ICLR_BASE + (ino * 8UL); |
233 | } | 233 | } |
234 | 234 | ||
235 | /* PCI SCHIZO INO number to Sparc PIL level. This table only matters for | ||
236 | * INOs which will not have an associated PCI device struct, ie. onboard | ||
237 | * EBUS devices and PCI controller internal error interrupts. | ||
238 | */ | ||
239 | static unsigned char schizo_pil_table[] = { | ||
240 | /*0x00*/0, 0, 0, 0, /* PCI slot 0 Int A, B, C, D */ | ||
241 | /*0x04*/0, 0, 0, 0, /* PCI slot 1 Int A, B, C, D */ | ||
242 | /*0x08*/0, 0, 0, 0, /* PCI slot 2 Int A, B, C, D */ | ||
243 | /*0x0c*/0, 0, 0, 0, /* PCI slot 3 Int A, B, C, D */ | ||
244 | /*0x10*/0, 0, 0, 0, /* PCI slot 4 Int A, B, C, D */ | ||
245 | /*0x14*/0, 0, 0, 0, /* PCI slot 5 Int A, B, C, D */ | ||
246 | /*0x18*/5, /* SCSI */ | ||
247 | /*0x19*/5, /* second SCSI */ | ||
248 | /*0x1a*/0, /* UNKNOWN */ | ||
249 | /*0x1b*/0, /* UNKNOWN */ | ||
250 | /*0x1c*/8, /* Parallel */ | ||
251 | /*0x1d*/5, /* Ethernet */ | ||
252 | /*0x1e*/8, /* Firewire-1394 */ | ||
253 | /*0x1f*/9, /* USB */ | ||
254 | /*0x20*/13, /* Audio Record */ | ||
255 | /*0x21*/14, /* Audio Playback */ | ||
256 | /*0x22*/12, /* Serial */ | ||
257 | /*0x23*/5, /* EBUS I2C */ | ||
258 | /*0x24*/10, /* RTC Clock */ | ||
259 | /*0x25*/11, /* Floppy */ | ||
260 | /*0x26*/0, /* UNKNOWN */ | ||
261 | /*0x27*/0, /* UNKNOWN */ | ||
262 | /*0x28*/0, /* UNKNOWN */ | ||
263 | /*0x29*/0, /* UNKNOWN */ | ||
264 | /*0x2a*/10, /* UPA 1 */ | ||
265 | /*0x2b*/10, /* UPA 2 */ | ||
266 | /*0x2c*/0, /* UNKNOWN */ | ||
267 | /*0x2d*/0, /* UNKNOWN */ | ||
268 | /*0x2e*/0, /* UNKNOWN */ | ||
269 | /*0x2f*/0, /* UNKNOWN */ | ||
270 | /*0x30*/15, /* Uncorrectable ECC */ | ||
271 | /*0x31*/15, /* Correctable ECC */ | ||
272 | /*0x32*/15, /* PCI Bus A Error */ | ||
273 | /*0x33*/15, /* PCI Bus B Error */ | ||
274 | /*0x34*/15, /* Safari Bus Error */ | ||
275 | /*0x35*/0, /* Reserved */ | ||
276 | /*0x36*/0, /* Reserved */ | ||
277 | /*0x37*/0, /* Reserved */ | ||
278 | /*0x38*/0, /* Reserved for NewLink */ | ||
279 | /*0x39*/0, /* Reserved for NewLink */ | ||
280 | /*0x3a*/0, /* Reserved for NewLink */ | ||
281 | /*0x3b*/0, /* Reserved for NewLink */ | ||
282 | /*0x3c*/0, /* Reserved for NewLink */ | ||
283 | /*0x3d*/0, /* Reserved for NewLink */ | ||
284 | /*0x3e*/0, /* Reserved for NewLink */ | ||
285 | /*0x3f*/0, /* Reserved for NewLink */ | ||
286 | }; | ||
287 | |||
288 | static int schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) | ||
289 | { | ||
290 | int ret; | ||
291 | |||
292 | if (pdev && | ||
293 | pdev->vendor == PCI_VENDOR_ID_SUN && | ||
294 | pdev->device == PCI_DEVICE_ID_SUN_RIO_USB) | ||
295 | return 9; | ||
296 | |||
297 | ret = schizo_pil_table[ino]; | ||
298 | if (ret == 0 && pdev == NULL) { | ||
299 | ret = 5; | ||
300 | } else if (ret == 0) { | ||
301 | switch ((pdev->class >> 16) & 0xff) { | ||
302 | case PCI_BASE_CLASS_STORAGE: | ||
303 | ret = 5; | ||
304 | break; | ||
305 | |||
306 | case PCI_BASE_CLASS_NETWORK: | ||
307 | ret = 6; | ||
308 | break; | ||
309 | |||
310 | case PCI_BASE_CLASS_DISPLAY: | ||
311 | ret = 9; | ||
312 | break; | ||
313 | |||
314 | case PCI_BASE_CLASS_MULTIMEDIA: | ||
315 | case PCI_BASE_CLASS_MEMORY: | ||
316 | case PCI_BASE_CLASS_BRIDGE: | ||
317 | case PCI_BASE_CLASS_SERIAL: | ||
318 | ret = 10; | ||
319 | break; | ||
320 | |||
321 | default: | ||
322 | ret = 5; | ||
323 | break; | ||
324 | }; | ||
325 | } | ||
326 | |||
327 | return ret; | ||
328 | } | ||
329 | |||
330 | static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) | 235 | static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) |
331 | { | 236 | { |
332 | unsigned long sync_reg = (unsigned long) _arg2; | 237 | unsigned long sync_reg = (unsigned long) _arg2; |
@@ -372,17 +277,12 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, | |||
372 | struct ino_bucket *bucket; | 277 | struct ino_bucket *bucket; |
373 | unsigned long imap, iclr; | 278 | unsigned long imap, iclr; |
374 | unsigned long imap_off, iclr_off; | 279 | unsigned long imap_off, iclr_off; |
375 | int pil, ign_fixup; | 280 | int ign_fixup; |
376 | 281 | ||
377 | ino &= PCI_IRQ_INO; | 282 | ino &= PCI_IRQ_INO; |
378 | imap_off = schizo_imap_offset(ino); | 283 | imap_off = schizo_imap_offset(ino); |
379 | 284 | ||
380 | /* Now build the IRQ bucket. */ | 285 | /* Now build the IRQ bucket. */ |
381 | pil = schizo_ino_to_pil(pdev, ino); | ||
382 | |||
383 | if (PIL_RESERVED(pil)) | ||
384 | BUG(); | ||
385 | |||
386 | imap = pbm->pbm_regs + imap_off; | 286 | imap = pbm->pbm_regs + imap_off; |
387 | imap += 4; | 287 | imap += 4; |
388 | 288 | ||
@@ -405,7 +305,7 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, | |||
405 | ign_fixup = (1 << 6); | 305 | ign_fixup = (1 << 6); |
406 | } | 306 | } |
407 | 307 | ||
408 | bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); | 308 | bucket = __bucket(build_irq(ign_fixup, iclr, imap)); |
409 | bucket->flags |= IBF_PCI; | 309 | bucket->flags |= IBF_PCI; |
410 | 310 | ||
411 | if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { | 311 | if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 0c0895202970..b97c81ba8835 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -843,38 +843,8 @@ static unsigned int pci_sun4v_irq_build(struct pci_pbm_info *pbm, | |||
843 | unsigned int devino) | 843 | unsigned int devino) |
844 | { | 844 | { |
845 | u32 devhandle = pbm->devhandle; | 845 | u32 devhandle = pbm->devhandle; |
846 | int pil; | ||
847 | 846 | ||
848 | pil = 5; | 847 | return sun4v_build_irq(devhandle, devino, IBF_PCI); |
849 | if (pdev) { | ||
850 | switch ((pdev->class >> 16) & 0xff) { | ||
851 | case PCI_BASE_CLASS_STORAGE: | ||
852 | pil = 5; | ||
853 | break; | ||
854 | |||
855 | case PCI_BASE_CLASS_NETWORK: | ||
856 | pil = 6; | ||
857 | break; | ||
858 | |||
859 | case PCI_BASE_CLASS_DISPLAY: | ||
860 | pil = 9; | ||
861 | break; | ||
862 | |||
863 | case PCI_BASE_CLASS_MULTIMEDIA: | ||
864 | case PCI_BASE_CLASS_MEMORY: | ||
865 | case PCI_BASE_CLASS_BRIDGE: | ||
866 | case PCI_BASE_CLASS_SERIAL: | ||
867 | pil = 10; | ||
868 | break; | ||
869 | |||
870 | default: | ||
871 | pil = 5; | ||
872 | break; | ||
873 | }; | ||
874 | } | ||
875 | BUG_ON(PIL_RESERVED(pil)); | ||
876 | |||
877 | return sun4v_build_irq(devhandle, devino, pil, IBF_PCI); | ||
878 | } | 848 | } |
879 | 849 | ||
880 | static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) | 850 | static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 1d6ffdeabd4c..8812417247d4 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -691,36 +691,6 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts) | |||
691 | upa_writeq(val, cfg_reg); | 691 | upa_writeq(val, cfg_reg); |
692 | } | 692 | } |
693 | 693 | ||
694 | /* SBUS SYSIO INO number to Sparc PIL level. */ | ||
695 | static unsigned char sysio_ino_to_pil[] = { | ||
696 | 0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 0 */ | ||
697 | 0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 1 */ | ||
698 | 0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 2 */ | ||
699 | 0, 5, 5, 7, 5, 7, 8, 9, /* SBUS slot 3 */ | ||
700 | 5, /* Onboard SCSI */ | ||
701 | 5, /* Onboard Ethernet */ | ||
702 | /*XXX*/ 8, /* Onboard BPP */ | ||
703 | 0, /* Bogon */ | ||
704 | 13, /* Audio */ | ||
705 | /*XXX*/15, /* PowerFail */ | ||
706 | 0, /* Bogon */ | ||
707 | 0, /* Bogon */ | ||
708 | 12, /* Zilog Serial Channels (incl. Keyboard/Mouse lines) */ | ||
709 | 11, /* Floppy */ | ||
710 | 0, /* Spare Hardware (bogon for now) */ | ||
711 | 0, /* Keyboard (bogon for now) */ | ||
712 | 0, /* Mouse (bogon for now) */ | ||
713 | 0, /* Serial (bogon for now) */ | ||
714 | 0, 0, /* Bogon, Bogon */ | ||
715 | 10, /* Timer 0 */ | ||
716 | 11, /* Timer 1 */ | ||
717 | 0, 0, /* Bogon, Bogon */ | ||
718 | 15, /* Uncorrectable SBUS Error */ | ||
719 | 15, /* Correctable SBUS Error */ | ||
720 | 15, /* SBUS Error */ | ||
721 | /*XXX*/ 0, /* Power Management (bogon for now) */ | ||
722 | }; | ||
723 | |||
724 | /* INO number to IMAP register offset for SYSIO external IRQ's. | 694 | /* INO number to IMAP register offset for SYSIO external IRQ's. |
725 | * This should conform to both Sunfire/Wildfire server and Fusion | 695 | * This should conform to both Sunfire/Wildfire server and Fusion |
726 | * desktop designs. | 696 | * desktop designs. |
@@ -812,21 +782,12 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) | |||
812 | struct sbus_iommu *iommu = sbus->iommu; | 782 | struct sbus_iommu *iommu = sbus->iommu; |
813 | unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; | 783 | unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL; |
814 | unsigned long imap, iclr; | 784 | unsigned long imap, iclr; |
815 | int pil, sbus_level = 0; | 785 | int sbus_level = 0; |
816 | |||
817 | pil = sysio_ino_to_pil[ino]; | ||
818 | if (!pil) { | ||
819 | printk("sbus_irq_build: Bad SYSIO INO[%x]\n", ino); | ||
820 | panic("Bad SYSIO IRQ translations..."); | ||
821 | } | ||
822 | |||
823 | if (PIL_RESERVED(pil)) | ||
824 | BUG(); | ||
825 | 786 | ||
826 | imap = sysio_irq_offsets[ino]; | 787 | imap = sysio_irq_offsets[ino]; |
827 | if (imap == ((unsigned long)-1)) { | 788 | if (imap == ((unsigned long)-1)) { |
828 | prom_printf("get_irq_translations: Bad SYSIO INO[%x] cpu[%d]\n", | 789 | prom_printf("get_irq_translations: Bad SYSIO INO[%x]\n", |
829 | ino, pil); | 790 | ino); |
830 | prom_halt(); | 791 | prom_halt(); |
831 | } | 792 | } |
832 | imap += reg_base; | 793 | imap += reg_base; |
@@ -860,7 +821,7 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) | |||
860 | 821 | ||
861 | iclr += ((unsigned long)sbus_level - 1UL) * 8UL; | 822 | iclr += ((unsigned long)sbus_level - 1UL) * 8UL; |
862 | } | 823 | } |
863 | return build_irq(pil, sbus_level, iclr, imap); | 824 | return build_irq(sbus_level, iclr, imap); |
864 | } | 825 | } |
865 | 826 | ||
866 | /* Error interrupt handling. */ | 827 | /* Error interrupt handling. */ |
diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index bbdf89e6faa4..d66c7cd820c2 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h | |||
@@ -37,14 +37,14 @@ struct irq_desc { | |||
37 | * line. Keep this in mind please. | 37 | * line. Keep this in mind please. |
38 | */ | 38 | */ |
39 | struct ino_bucket { | 39 | struct ino_bucket { |
40 | /* Next handler in per-CPU PIL worklist. We know that | 40 | /* Next handler in per-CPU IRQ worklist. We know that |
41 | * bucket pointers have the high 32-bits clear, so to | 41 | * bucket pointers have the high 32-bits clear, so to |
42 | * save space we only store the bits we need. | 42 | * save space we only store the bits we need. |
43 | */ | 43 | */ |
44 | /*0x00*/unsigned int irq_chain; | 44 | /*0x00*/unsigned int irq_chain; |
45 | 45 | ||
46 | /* PIL to schedule this IVEC at. */ | 46 | /* Virtual interrupt number assigned to this INO. */ |
47 | /*0x04*/unsigned char pil; | 47 | /*0x04*/unsigned char virt_irq; |
48 | 48 | ||
49 | /* If an IVEC arrives while irq_info is NULL, we | 49 | /* If an IVEC arrives while irq_info is NULL, we |
50 | * set this to notify request_irq() about the event. | 50 | * set this to notify request_irq() about the event. |
@@ -95,7 +95,6 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; | |||
95 | 95 | ||
96 | #define __irq_ino(irq) \ | 96 | #define __irq_ino(irq) \ |
97 | (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) | 97 | (((struct ino_bucket *)(unsigned long)(irq)) - &ivector_table[0]) |
98 | #define __irq_pil(irq) ((struct ino_bucket *)(unsigned long)(irq))->pil | ||
99 | #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) | 98 | #define __bucket(irq) ((struct ino_bucket *)(unsigned long)(irq)) |
100 | #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) | 99 | #define __irq(bucket) ((unsigned int)(unsigned long)(bucket)) |
101 | 100 | ||
@@ -105,8 +104,8 @@ extern struct ino_bucket ivector_table[NUM_IVECS]; | |||
105 | extern void disable_irq(unsigned int); | 104 | extern void disable_irq(unsigned int); |
106 | #define disable_irq_nosync disable_irq | 105 | #define disable_irq_nosync disable_irq |
107 | extern void enable_irq(unsigned int); | 106 | extern void enable_irq(unsigned int); |
108 | extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); | 107 | extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); |
109 | extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags); | 108 | extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags); |
110 | extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); | 109 | extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); |
111 | 110 | ||
112 | static __inline__ void set_softint(unsigned long bits) | 111 | static __inline__ void set_softint(unsigned long bits) |