aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r--arch/sparc64/kernel/irq.c72
1 files changed, 39 insertions, 33 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index c72795666a62..db31bf6b42db 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -87,7 +87,11 @@ struct ino_bucket ivector_table[NUM_IVECS] __attribute__ ((aligned (SMP_CACHE_BY
87 */ 87 */
88#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist) 88#define irq_work(__cpu) &(trap_block[(__cpu)].irq_worklist)
89 89
90static unsigned int virt_to_real_irq_table[NR_IRQS]; 90static struct {
91 unsigned int irq;
92 unsigned int dev_handle;
93 unsigned int dev_ino;
94} virt_to_real_irq_table[NR_IRQS];
91 95
92static unsigned char virt_irq_alloc(unsigned int real_irq) 96static unsigned char virt_irq_alloc(unsigned int real_irq)
93{ 97{
@@ -96,7 +100,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
96 BUILD_BUG_ON(NR_IRQS >= 256); 100 BUILD_BUG_ON(NR_IRQS >= 256);
97 101
98 for (ent = 1; ent < NR_IRQS; ent++) { 102 for (ent = 1; ent < NR_IRQS; ent++) {
99 if (!virt_to_real_irq_table[ent]) 103 if (!virt_to_real_irq_table[ent].irq)
100 break; 104 break;
101 } 105 }
102 if (ent >= NR_IRQS) { 106 if (ent >= NR_IRQS) {
@@ -104,7 +108,7 @@ static unsigned char virt_irq_alloc(unsigned int real_irq)
104 return 0; 108 return 0;
105 } 109 }
106 110
107 virt_to_real_irq_table[ent] = real_irq; 111 virt_to_real_irq_table[ent].irq = real_irq;
108 112
109 return ent; 113 return ent;
110} 114}
@@ -117,8 +121,8 @@ static void virt_irq_free(unsigned int virt_irq)
117 if (virt_irq >= NR_IRQS) 121 if (virt_irq >= NR_IRQS)
118 return; 122 return;
119 123
120 real_irq = virt_to_real_irq_table[virt_irq]; 124 real_irq = virt_to_real_irq_table[virt_irq].irq;
121 virt_to_real_irq_table[virt_irq] = 0; 125 virt_to_real_irq_table[virt_irq].irq = 0;
122 126
123 __bucket(real_irq)->virt_irq = 0; 127 __bucket(real_irq)->virt_irq = 0;
124} 128}
@@ -126,7 +130,7 @@ static void virt_irq_free(unsigned int virt_irq)
126 130
127static unsigned int virt_to_real_irq(unsigned char virt_irq) 131static unsigned int virt_to_real_irq(unsigned char virt_irq)
128{ 132{
129 return virt_to_real_irq_table[virt_irq]; 133 return virt_to_real_irq_table[virt_irq].irq;
130} 134}
131 135
132/* 136/*
@@ -336,15 +340,15 @@ static void sun4v_irq_enable(unsigned int virt_irq)
336 340
337 err = sun4v_intr_settarget(ino, cpuid); 341 err = sun4v_intr_settarget(ino, cpuid);
338 if (err != HV_EOK) 342 if (err != HV_EOK)
339 printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", 343 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
340 ino, cpuid, err); 344 "err(%d)\n", ino, cpuid, err);
341 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 345 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
342 if (err != HV_EOK) 346 if (err != HV_EOK)
343 printk("sun4v_intr_setstate(%x): " 347 printk(KERN_ERR "sun4v_intr_setstate(%x): "
344 "err(%d)\n", ino, err); 348 "err(%d)\n", ino, err);
345 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); 349 err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED);
346 if (err != HV_EOK) 350 if (err != HV_EOK)
347 printk("sun4v_intr_setenabled(%x): err(%d)\n", 351 printk(KERN_ERR "sun4v_intr_setenabled(%x): err(%d)\n",
348 ino, err); 352 ino, err);
349 } 353 }
350} 354}
@@ -362,8 +366,8 @@ static void sun4v_set_affinity(unsigned int virt_irq, cpumask_t mask)
362 366
363 err = sun4v_intr_settarget(ino, cpuid); 367 err = sun4v_intr_settarget(ino, cpuid);
364 if (err != HV_EOK) 368 if (err != HV_EOK)
365 printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", 369 printk(KERN_ERR "sun4v_intr_settarget(%x,%lu): "
366 ino, cpuid, err); 370 "err(%d)\n", ino, cpuid, err);
367 } 371 }
368} 372}
369 373
@@ -377,7 +381,7 @@ static void sun4v_irq_disable(unsigned int virt_irq)
377 381
378 err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); 382 err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED);
379 if (err != HV_EOK) 383 if (err != HV_EOK)
380 printk("sun4v_intr_setenabled(%x): " 384 printk(KERN_ERR "sun4v_intr_setenabled(%x): "
381 "err(%d)\n", ino, err); 385 "err(%d)\n", ino, err);
382 } 386 }
383} 387}
@@ -410,7 +414,7 @@ static void sun4v_irq_end(unsigned int virt_irq)
410 414
411 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); 415 err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
412 if (err != HV_EOK) 416 if (err != HV_EOK)
413 printk("sun4v_intr_setstate(%x): " 417 printk(KERN_ERR "sun4v_intr_setstate(%x): "
414 "err(%d)\n", ino, err); 418 "err(%d)\n", ino, err);
415 } 419 }
416} 420}
@@ -418,7 +422,6 @@ static void sun4v_irq_end(unsigned int virt_irq)
418static void sun4v_virq_enable(unsigned int virt_irq) 422static void sun4v_virq_enable(unsigned int virt_irq)
419{ 423{
420 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 424 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
421 unsigned int ino = bucket - &ivector_table[0];
422 425
423 if (likely(bucket)) { 426 if (likely(bucket)) {
424 unsigned long cpuid, dev_handle, dev_ino; 427 unsigned long cpuid, dev_handle, dev_ino;
@@ -426,24 +429,24 @@ static void sun4v_virq_enable(unsigned int virt_irq)
426 429
427 cpuid = irq_choose_cpu(virt_irq); 430 cpuid = irq_choose_cpu(virt_irq);
428 431
429 dev_handle = ino & IMAP_IGN; 432 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
430 dev_ino = ino & IMAP_INO; 433 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
431 434
432 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); 435 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
433 if (err != HV_EOK) 436 if (err != HV_EOK)
434 printk("sun4v_vintr_set_target(%lx,%lx,%lu): " 437 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
435 "err(%d)\n", 438 "err(%d)\n",
436 dev_handle, dev_ino, cpuid, err); 439 dev_handle, dev_ino, cpuid, err);
437 err = sun4v_vintr_set_state(dev_handle, dev_ino, 440 err = sun4v_vintr_set_state(dev_handle, dev_ino,
438 HV_INTR_STATE_IDLE); 441 HV_INTR_STATE_IDLE);
439 if (err != HV_EOK) 442 if (err != HV_EOK)
440 printk("sun4v_vintr_set_state(%lx,%lx," 443 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
441 "HV_INTR_STATE_IDLE): err(%d)\n", 444 "HV_INTR_STATE_IDLE): err(%d)\n",
442 dev_handle, dev_ino, err); 445 dev_handle, dev_ino, err);
443 err = sun4v_vintr_set_valid(dev_handle, dev_ino, 446 err = sun4v_vintr_set_valid(dev_handle, dev_ino,
444 HV_INTR_ENABLED); 447 HV_INTR_ENABLED);
445 if (err != HV_EOK) 448 if (err != HV_EOK)
446 printk("sun4v_vintr_set_state(%lx,%lx," 449 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
447 "HV_INTR_ENABLED): err(%d)\n", 450 "HV_INTR_ENABLED): err(%d)\n",
448 dev_handle, dev_ino, err); 451 dev_handle, dev_ino, err);
449 } 452 }
@@ -452,7 +455,6 @@ static void sun4v_virq_enable(unsigned int virt_irq)
452static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) 455static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
453{ 456{
454 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 457 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
455 unsigned int ino = bucket - &ivector_table[0];
456 458
457 if (likely(bucket)) { 459 if (likely(bucket)) {
458 unsigned long cpuid, dev_handle, dev_ino; 460 unsigned long cpuid, dev_handle, dev_ino;
@@ -460,12 +462,12 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
460 462
461 cpuid = irq_choose_cpu(virt_irq); 463 cpuid = irq_choose_cpu(virt_irq);
462 464
463 dev_handle = ino & IMAP_IGN; 465 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
464 dev_ino = ino & IMAP_INO; 466 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
465 467
466 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); 468 err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid);
467 if (err != HV_EOK) 469 if (err != HV_EOK)
468 printk("sun4v_vintr_set_target(%lx,%lx,%lu): " 470 printk(KERN_ERR "sun4v_vintr_set_target(%lx,%lx,%lu): "
469 "err(%d)\n", 471 "err(%d)\n",
470 dev_handle, dev_ino, cpuid, err); 472 dev_handle, dev_ino, cpuid, err);
471 } 473 }
@@ -474,19 +476,18 @@ static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask)
474static void sun4v_virq_disable(unsigned int virt_irq) 476static void sun4v_virq_disable(unsigned int virt_irq)
475{ 477{
476 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 478 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
477 unsigned int ino = bucket - &ivector_table[0];
478 479
479 if (likely(bucket)) { 480 if (likely(bucket)) {
480 unsigned long dev_handle, dev_ino; 481 unsigned long dev_handle, dev_ino;
481 int err; 482 int err;
482 483
483 dev_handle = ino & IMAP_IGN; 484 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
484 dev_ino = ino & IMAP_INO; 485 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
485 486
486 err = sun4v_vintr_set_valid(dev_handle, dev_ino, 487 err = sun4v_vintr_set_valid(dev_handle, dev_ino,
487 HV_INTR_DISABLED); 488 HV_INTR_DISABLED);
488 if (err != HV_EOK) 489 if (err != HV_EOK)
489 printk("sun4v_vintr_set_state(%lx,%lx," 490 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
490 "HV_INTR_DISABLED): err(%d)\n", 491 "HV_INTR_DISABLED): err(%d)\n",
491 dev_handle, dev_ino, err); 492 dev_handle, dev_ino, err);
492 } 493 }
@@ -495,7 +496,6 @@ static void sun4v_virq_disable(unsigned int virt_irq)
495static void sun4v_virq_end(unsigned int virt_irq) 496static void sun4v_virq_end(unsigned int virt_irq)
496{ 497{
497 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); 498 struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq);
498 unsigned int ino = bucket - &ivector_table[0];
499 struct irq_desc *desc = irq_desc + virt_irq; 499 struct irq_desc *desc = irq_desc + virt_irq;
500 500
501 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) 501 if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
@@ -505,13 +505,13 @@ static void sun4v_virq_end(unsigned int virt_irq)
505 unsigned long dev_handle, dev_ino; 505 unsigned long dev_handle, dev_ino;
506 int err; 506 int err;
507 507
508 dev_handle = ino & IMAP_IGN; 508 dev_handle = virt_to_real_irq_table[virt_irq].dev_handle;
509 dev_ino = ino & IMAP_INO; 509 dev_ino = virt_to_real_irq_table[virt_irq].dev_ino;
510 510
511 err = sun4v_vintr_set_state(dev_handle, dev_ino, 511 err = sun4v_vintr_set_state(dev_handle, dev_ino,
512 HV_INTR_STATE_IDLE); 512 HV_INTR_STATE_IDLE);
513 if (err != HV_EOK) 513 if (err != HV_EOK)
514 printk("sun4v_vintr_set_state(%lx,%lx," 514 printk(KERN_ERR "sun4v_vintr_set_state(%lx,%lx,"
515 "HV_INTR_STATE_IDLE): err(%d)\n", 515 "HV_INTR_STATE_IDLE): err(%d)\n",
516 dev_handle, dev_ino, err); 516 dev_handle, dev_ino, err);
517 } 517 }
@@ -700,6 +700,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
700unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) 700unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
701{ 701{
702 unsigned long sysino, hv_err; 702 unsigned long sysino, hv_err;
703 unsigned int virq;
703 704
704 BUG_ON(devhandle & devino); 705 BUG_ON(devhandle & devino);
705 706
@@ -713,7 +714,12 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
713 prom_halt(); 714 prom_halt();
714 } 715 }
715 716
716 return sun4v_build_common(sysino, &sun4v_virq); 717 virq = sun4v_build_common(sysino, &sun4v_virq);
718
719 virt_to_real_irq_table[virq].dev_handle = devhandle;
720 virt_to_real_irq_table[virq].dev_ino = devino;
721
722 return virq;
717} 723}
718 724
719#ifdef CONFIG_PCI_MSI 725#ifdef CONFIG_PCI_MSI