Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

genirq: Use irq_resolve_mapping() to implement __handle_domain_irq() and co

In order to start reaping the benefits of irq_resolve_mapping(),
start using it in __handle_domain_irq() and handle_domain_nmi().

This involves splitting generic_handle_irq() to be able to directly
provide the irq_desc.

Signed-off-by: Marc Zyngier <maz@kernel.org>

+36 -25
+1
include/linux/irqdesc.h
··· 158 158 desc->handle_irq(desc); 159 159 } 160 160 161 + int handle_irq_desc(struct irq_desc *desc); 161 162 int generic_handle_irq(unsigned int irq); 162 163 163 164 #ifdef CONFIG_HANDLE_DOMAIN_IRQ
+35 -25
kernel/irq/irqdesc.c
··· 632 632 633 633 #endif /* !CONFIG_SPARSE_IRQ */ 634 634 635 - /** 636 - * generic_handle_irq - Invoke the handler for a particular irq 637 - * @irq: The irq number to handle 638 - * 639 - */ 640 - int generic_handle_irq(unsigned int irq) 635 + int handle_irq_desc(struct irq_desc *desc) 641 636 { 642 - struct irq_desc *desc = irq_to_desc(irq); 643 637 struct irq_data *data; 644 638 645 639 if (!desc) ··· 645 651 646 652 generic_handle_irq_desc(desc); 647 653 return 0; 654 + } 655 + EXPORT_SYMBOL_GPL(handle_irq_desc); 656 + 657 + /** 658 + * generic_handle_irq - Invoke the handler for a particular irq 659 + * @irq: The irq number to handle 660 + * 661 + */ 662 + int generic_handle_irq(unsigned int irq) 663 + { 664 + return handle_irq_desc(irq_to_desc(irq)); 648 665 } 649 666 EXPORT_SYMBOL_GPL(generic_handle_irq); 650 667 ··· 673 668 bool lookup, struct pt_regs *regs) 674 669 { 675 670 struct pt_regs *old_regs = set_irq_regs(regs); 676 - unsigned int irq = hwirq; 671 + struct irq_desc *desc; 677 672 int ret = 0; 678 673 679 674 irq_enter(); 680 675 681 - #ifdef CONFIG_IRQ_DOMAIN 682 - if (lookup) 683 - irq = irq_find_mapping(domain, hwirq); 684 - #endif 685 - 686 - /* 687 - * Some hardware gives randomly wrong interrupts. Rather 688 - * than crashing, do something sensible. 689 - */ 690 - if (unlikely(!irq || irq >= nr_irqs)) { 691 - ack_bad_irq(irq); 692 - ret = -EINVAL; 676 + if (likely(IS_ENABLED(CONFIG_IRQ_DOMAIN) && lookup)) { 677 + /* The irqdomain code provides boundary checks */ 678 + desc = irq_resolve_mapping(domain, hwirq); 693 679 } else { 694 - generic_handle_irq(irq); 680 + /* 681 + * Some hardware gives randomly wrong interrupts. Rather 682 + * than crashing, do something sensible. 683 + */ 684 + if (unlikely(!hwirq || hwirq >= nr_irqs)) { 685 + ack_bad_irq(hwirq); 686 + desc = NULL; 687 + } else { 688 + desc = irq_to_desc(hwirq); 689 + } 695 690 } 691 + 692 + if (likely(desc)) 693 + handle_irq_desc(desc); 694 + else 695 + ret = -EINVAL; 696 696 697 697 irq_exit(); 698 698 set_irq_regs(old_regs); ··· 719 709 struct pt_regs *regs) 720 710 { 721 711 struct pt_regs *old_regs = set_irq_regs(regs); 722 - unsigned int irq; 712 + struct irq_desc *desc; 723 713 int ret = 0; 724 714 725 715 /* ··· 727 717 */ 728 718 WARN_ON(!in_nmi()); 729 719 730 - irq = irq_find_mapping(domain, hwirq); 720 + desc = irq_resolve_mapping(domain, hwirq); 731 721 732 722 /* 733 723 * ack_bad_irq is not NMI-safe, just report 734 724 * an invalid interrupt. 735 725 */ 736 - if (likely(irq)) 737 - generic_handle_irq(irq); 726 + if (likely(desc)) 727 + handle_irq_desc(desc); 738 728 else 739 729 ret = -EINVAL; 740 730