diff options
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r-- | arch/sparc64/kernel/irq.c | 72 |
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 | ||
90 | static unsigned int virt_to_real_irq_table[NR_IRQS]; | 90 | static 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 | ||
92 | static unsigned char virt_irq_alloc(unsigned int real_irq) | 96 | static 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 | ||
127 | static unsigned int virt_to_real_irq(unsigned char virt_irq) | 131 | static 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) | |||
418 | static void sun4v_virq_enable(unsigned int virt_irq) | 422 | static 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) | |||
452 | static void sun4v_virt_set_affinity(unsigned int virt_irq, cpumask_t mask) | 455 | static 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) | |||
474 | static void sun4v_virq_disable(unsigned int virt_irq) | 476 | static 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) | |||
495 | static void sun4v_virq_end(unsigned int virt_irq) | 496 | static 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) | |||
700 | unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | 700 | unsigned 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 |