diff options
Diffstat (limited to 'kernel/irq/irqdesc.c')
-rw-r--r-- | kernel/irq/irqdesc.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 84fa255d0329..13539e12cd80 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c | |||
@@ -670,6 +670,41 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, | |||
670 | set_irq_regs(old_regs); | 670 | set_irq_regs(old_regs); |
671 | return ret; | 671 | return ret; |
672 | } | 672 | } |
673 | |||
674 | #ifdef CONFIG_IRQ_DOMAIN | ||
675 | /** | ||
676 | * handle_domain_nmi - Invoke the handler for a HW irq belonging to a domain | ||
677 | * @domain: The domain where to perform the lookup | ||
678 | * @hwirq: The HW irq number to convert to a logical one | ||
679 | * @regs: Register file coming from the low-level handling code | ||
680 | * | ||
681 | * Returns: 0 on success, or -EINVAL if conversion has failed | ||
682 | */ | ||
683 | int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, | ||
684 | struct pt_regs *regs) | ||
685 | { | ||
686 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
687 | unsigned int irq; | ||
688 | int ret = 0; | ||
689 | |||
690 | nmi_enter(); | ||
691 | |||
692 | irq = irq_find_mapping(domain, hwirq); | ||
693 | |||
694 | /* | ||
695 | * ack_bad_irq is not NMI-safe, just report | ||
696 | * an invalid interrupt. | ||
697 | */ | ||
698 | if (likely(irq)) | ||
699 | generic_handle_irq(irq); | ||
700 | else | ||
701 | ret = -EINVAL; | ||
702 | |||
703 | nmi_exit(); | ||
704 | set_irq_regs(old_regs); | ||
705 | return ret; | ||
706 | } | ||
707 | #endif | ||
673 | #endif | 708 | #endif |
674 | 709 | ||
675 | /* Dynamic interrupt handling */ | 710 | /* Dynamic interrupt handling */ |