Skip to content

Commit a3016b2

Browse files
author
Marc Zyngier
committed
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 <[email protected]>
1 parent d22558d commit a3016b2

File tree

2 files changed

+36
-25
lines changed

2 files changed

+36
-25
lines changed

include/linux/irqdesc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ static inline void generic_handle_irq_desc(struct irq_desc *desc)
158158
desc->handle_irq(desc);
159159
}
160160

161+
int handle_irq_desc(struct irq_desc *desc);
161162
int generic_handle_irq(unsigned int irq);
162163

163164
#ifdef CONFIG_HANDLE_DOMAIN_IRQ

kernel/irq/irqdesc.c

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -632,14 +632,8 @@ void irq_init_desc(unsigned int irq)
632632

633633
#endif /* !CONFIG_SPARSE_IRQ */
634634

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)
641636
{
642-
struct irq_desc *desc = irq_to_desc(irq);
643637
struct irq_data *data;
644638

645639
if (!desc)
@@ -652,6 +646,17 @@ int generic_handle_irq(unsigned int irq)
652646
generic_handle_irq_desc(desc);
653647
return 0;
654648
}
649+
EXPORT_SYMBOL_GPL(handle_irq_desc);
650+
651+
/**
652+
* generic_handle_irq - Invoke the handler for a particular irq
653+
* @irq: The irq number to handle
654+
*
655+
*/
656+
int generic_handle_irq(unsigned int irq)
657+
{
658+
return handle_irq_desc(irq_to_desc(irq));
659+
}
655660
EXPORT_SYMBOL_GPL(generic_handle_irq);
656661

657662
#ifdef CONFIG_HANDLE_DOMAIN_IRQ
@@ -668,27 +673,32 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
668673
bool lookup, struct pt_regs *regs)
669674
{
670675
struct pt_regs *old_regs = set_irq_regs(regs);
671-
unsigned int irq = hwirq;
676+
struct irq_desc *desc;
672677
int ret = 0;
673678

674679
irq_enter();
675680

676-
#ifdef CONFIG_IRQ_DOMAIN
677-
if (lookup)
678-
irq = irq_find_mapping(domain, hwirq);
679-
#endif
680-
681-
/*
682-
* Some hardware gives randomly wrong interrupts. Rather
683-
* than crashing, do something sensible.
684-
*/
685-
if (unlikely(!irq || irq >= nr_irqs)) {
686-
ack_bad_irq(irq);
687-
ret = -EINVAL;
681+
if (likely(IS_ENABLED(CONFIG_IRQ_DOMAIN) && lookup)) {
682+
/* The irqdomain code provides boundary checks */
683+
desc = irq_resolve_mapping(domain, hwirq);
688684
} else {
689-
generic_handle_irq(irq);
685+
/*
686+
* Some hardware gives randomly wrong interrupts. Rather
687+
* than crashing, do something sensible.
688+
*/
689+
if (unlikely(!hwirq || hwirq >= nr_irqs)) {
690+
ack_bad_irq(hwirq);
691+
desc = NULL;
692+
} else {
693+
desc = irq_to_desc(hwirq);
694+
}
690695
}
691696

697+
if (likely(desc))
698+
handle_irq_desc(desc);
699+
else
700+
ret = -EINVAL;
701+
692702
irq_exit();
693703
set_irq_regs(old_regs);
694704
return ret;
@@ -709,22 +719,22 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
709719
struct pt_regs *regs)
710720
{
711721
struct pt_regs *old_regs = set_irq_regs(regs);
712-
unsigned int irq;
722+
struct irq_desc *desc;
713723
int ret = 0;
714724

715725
/*
716726
* NMI context needs to be setup earlier in order to deal with tracing.
717727
*/
718728
WARN_ON(!in_nmi());
719729

720-
irq = irq_find_mapping(domain, hwirq);
730+
desc = irq_resolve_mapping(domain, hwirq);
721731

722732
/*
723733
* ack_bad_irq is not NMI-safe, just report
724734
* an invalid interrupt.
725735
*/
726-
if (likely(irq))
727-
generic_handle_irq(irq);
736+
if (likely(desc))
737+
handle_irq_desc(desc);
728738
else
729739
ret = -EINVAL;
730740

0 commit comments

Comments
 (0)