diff options
Diffstat (limited to 'arch/sparc64/kernel/irq.c')
-rw-r--r-- | arch/sparc64/kernel/irq.c | 37 |
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 | ||
644 | unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | 644 | unsigned 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 | ||
669 | void ack_bad_irq(unsigned int virt_irq) | 684 | void ack_bad_irq(unsigned int virt_irq) |