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.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 5a92851296c0..4e9537c96778 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -643,27 +643,42 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
643 643
644unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) 644unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
645{ 645{
646 unsigned long sysino, hv_err; 646 struct irq_handler_data *data;
647 unsigned int virq; 647 struct ino_bucket *bucket;
648 unsigned long hv_err, cookie;
649
650 bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
651 if (unlikely(!bucket))
652 return 0;
653
654 bucket->virt_irq = virt_irq_alloc(__irq(bucket));
655 set_irq_chip(bucket->virt_irq, &sun4v_virq);
648 656
649 BUG_ON(devhandle & devino); 657 data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
658 if (unlikely(!data))
659 return 0;
650 660
651 sysino = devhandle | devino; 661 set_irq_chip_data(bucket->virt_irq, data);
652 BUG_ON(sysino & ~(IMAP_IGN | IMAP_INO));
653 662
654 hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); 663 /* Catch accidental accesses to these things. IMAP/ICLR handling
664 * is done by hypervisor calls on sun4v platforms, not by direct
665 * register accesses.
666 */
667 data->imap = ~0UL;
668 data->iclr = ~0UL;
669
670 cookie = ~__pa(bucket);
671 hv_err = sun4v_vintr_set_cookie(devhandle, devino, cookie);
655 if (hv_err) { 672 if (hv_err) {
656 prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] " 673 prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] "
657 "err=%lu\n", devhandle, devino, hv_err); 674 "err=%lu\n", devhandle, devino, hv_err);
658 prom_halt(); 675 prom_halt();
659 } 676 }
660 677
661 virq = sun4v_build_common(sysino, &sun4v_virq); 678 virt_to_real_irq_table[bucket->virt_irq].dev_handle = devhandle;
662 679 virt_to_real_irq_table[bucket->virt_irq].dev_ino = devino;
663 virt_to_real_irq_table[virq].dev_handle = devhandle;
664 virt_to_real_irq_table[virq].dev_ino = devino;
665 680
666 return virq; 681 return bucket->virt_irq;
667} 682}
668 683
669void ack_bad_irq(unsigned int virt_irq) 684void ack_bad_irq(unsigned int virt_irq)