aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc64/kernel/devices.c2
-rw-r--r--arch/sparc64/kernel/irq.c70
-rw-r--r--arch/sparc64/kernel/pci_psycho.c77
-rw-r--r--arch/sparc64/kernel/pci_sabre.c81
-rw-r--r--arch/sparc64/kernel/pci_schizo.c104
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c32
-rw-r--r--arch/sparc64/kernel/sbus.c47
-rw-r--r--include/asm-sparc64/irq.h11
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
163static const char *cpu_mid_prop(void) 163static 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
73static struct irqaction *irq_action[NR_IRQS+1]; 73static 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 }
127out_unlock: 124out_unlock:
@@ -245,48 +242,47 @@ void disable_irq(unsigned int irq)
245 } 242 }
246} 243}
247 244
248static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, 245static 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
259unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) 256unsigned 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
308out: 303out:
309 return __irq(bucket); 304 return __irq(bucket);
310} 305}
311 306
312unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags) 307unsigned 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
357static int check_irq_sharing(int pil, unsigned long irqflags) 351static 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
479static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) 469static 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);
652out: 641out:
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. */
280static 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
310static 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
347static unsigned int psycho_irq_build(struct pci_pbm_info *pbm, 279static 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. */
527static 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
557static 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 */
239static 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
288static 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
330static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) 235static 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
880static void pci_sun4v_base_address_update(struct pci_dev *pdev, int resource) 850static 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. */
695static 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 */
39struct ino_bucket { 39struct 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];
105extern void disable_irq(unsigned int); 104extern void disable_irq(unsigned int);
106#define disable_irq_nosync disable_irq 105#define disable_irq_nosync disable_irq
107extern void enable_irq(unsigned int); 106extern void enable_irq(unsigned int);
108extern unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap); 107extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap);
109extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, int pil, unsigned char flags); 108extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino, unsigned char flags);
110extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); 109extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
111 110
112static __inline__ void set_softint(unsigned long bits) 111static __inline__ void set_softint(unsigned long bits)