Commit a3016b26 authored by Marc Zyngier's avatar Marc Zyngier

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: default avatarMarc Zyngier <maz@kernel.org>
parent d22558dd
...@@ -158,6 +158,7 @@ static inline void generic_handle_irq_desc(struct irq_desc *desc) ...@@ -158,6 +158,7 @@ static inline void generic_handle_irq_desc(struct irq_desc *desc)
desc->handle_irq(desc); desc->handle_irq(desc);
} }
int handle_irq_desc(struct irq_desc *desc);
int generic_handle_irq(unsigned int irq); int generic_handle_irq(unsigned int irq);
#ifdef CONFIG_HANDLE_DOMAIN_IRQ #ifdef CONFIG_HANDLE_DOMAIN_IRQ
......
...@@ -632,14 +632,8 @@ void irq_init_desc(unsigned int irq) ...@@ -632,14 +632,8 @@ void irq_init_desc(unsigned int irq)
#endif /* !CONFIG_SPARSE_IRQ */ #endif /* !CONFIG_SPARSE_IRQ */
/** int handle_irq_desc(struct irq_desc *desc)
* generic_handle_irq - Invoke the handler for a particular irq
* @irq: The irq number to handle
*
*/
int generic_handle_irq(unsigned int irq)
{ {
struct irq_desc *desc = irq_to_desc(irq);
struct irq_data *data; struct irq_data *data;
if (!desc) if (!desc)
...@@ -652,6 +646,17 @@ int generic_handle_irq(unsigned int irq) ...@@ -652,6 +646,17 @@ int generic_handle_irq(unsigned int irq)
generic_handle_irq_desc(desc); generic_handle_irq_desc(desc);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(handle_irq_desc);
/**
* generic_handle_irq - Invoke the handler for a particular irq
* @irq: The irq number to handle
*
*/
int generic_handle_irq(unsigned int irq)
{
return handle_irq_desc(irq_to_desc(irq));
}
EXPORT_SYMBOL_GPL(generic_handle_irq); EXPORT_SYMBOL_GPL(generic_handle_irq);
#ifdef CONFIG_HANDLE_DOMAIN_IRQ #ifdef CONFIG_HANDLE_DOMAIN_IRQ
...@@ -668,27 +673,32 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, ...@@ -668,27 +673,32 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq,
bool lookup, struct pt_regs *regs) bool lookup, struct pt_regs *regs)
{ {
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
unsigned int irq = hwirq; struct irq_desc *desc;
int ret = 0; int ret = 0;
irq_enter(); irq_enter();
#ifdef CONFIG_IRQ_DOMAIN if (likely(IS_ENABLED(CONFIG_IRQ_DOMAIN) && lookup)) {
if (lookup) /* The irqdomain code provides boundary checks */
irq = irq_find_mapping(domain, hwirq); desc = irq_resolve_mapping(domain, hwirq);
#endif } else {
/* /*
* Some hardware gives randomly wrong interrupts. Rather * Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible. * than crashing, do something sensible.
*/ */
if (unlikely(!irq || irq >= nr_irqs)) { if (unlikely(!hwirq || hwirq >= nr_irqs)) {
ack_bad_irq(irq); ack_bad_irq(hwirq);
ret = -EINVAL; desc = NULL;
} else { } else {
generic_handle_irq(irq); desc = irq_to_desc(hwirq);
}
} }
if (likely(desc))
handle_irq_desc(desc);
else
ret = -EINVAL;
irq_exit(); irq_exit();
set_irq_regs(old_regs); set_irq_regs(old_regs);
return ret; return ret;
...@@ -709,7 +719,7 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, ...@@ -709,7 +719,7 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct pt_regs *old_regs = set_irq_regs(regs); struct pt_regs *old_regs = set_irq_regs(regs);
unsigned int irq; struct irq_desc *desc;
int ret = 0; int ret = 0;
/* /*
...@@ -717,14 +727,14 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq, ...@@ -717,14 +727,14 @@ int handle_domain_nmi(struct irq_domain *domain, unsigned int hwirq,
*/ */
WARN_ON(!in_nmi()); WARN_ON(!in_nmi());
irq = irq_find_mapping(domain, hwirq); desc = irq_resolve_mapping(domain, hwirq);
/* /*
* ack_bad_irq is not NMI-safe, just report * ack_bad_irq is not NMI-safe, just report
* an invalid interrupt. * an invalid interrupt.
*/ */
if (likely(irq)) if (likely(desc))
generic_handle_irq(irq); handle_irq_desc(desc);
else else
ret = -EINVAL; ret = -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment