genirq: Add preflow handler support

sparc64 needs to call a preflow handler on certain interrupts befor
calling the action chain. Integrate it into handle_fasteoi_irq. Must
be enabled via CONFIG_IRQ_FASTEOI_PREFLOW. No impact when disabled.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: David S. Miller <davem@davemloft.net>
This commit is contained in:
Thomas Gleixner 2011-02-10 15:14:20 +01:00
parent 3836ca08aa
commit 781295762d
4 changed files with 30 additions and 1 deletions

View File

@ -29,9 +29,10 @@
#include <asm/irq_regs.h> #include <asm/irq_regs.h>
struct irq_desc; struct irq_desc;
struct irq_data;
typedef void (*irq_flow_handler_t)(unsigned int irq, typedef void (*irq_flow_handler_t)(unsigned int irq,
struct irq_desc *desc); struct irq_desc *desc);
typedef void (*irq_preflow_handler_t)(struct irq_data *data);
/* /*
* IRQ line status. * IRQ line status.

View File

@ -63,6 +63,9 @@ struct irq_desc {
struct timer_rand_state *timer_rand_state; struct timer_rand_state *timer_rand_state;
unsigned int __percpu *kstat_irqs; unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq; irq_flow_handler_t handle_irq;
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
irq_preflow_handler_t preflow_handler;
#endif
struct irqaction *action; /* IRQ action list */ struct irqaction *action; /* IRQ action list */
#ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT #ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
unsigned int status_use_accessors; unsigned int status_use_accessors;
@ -187,6 +190,17 @@ static inline void __set_irq_handler_unlocked(int irq,
desc = irq_to_desc(irq); desc = irq_to_desc(irq);
desc->handle_irq = handler; desc->handle_irq = handler;
} }
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
static inline void
__irq_set_preflow_handler(unsigned int irq, irq_preflow_handler_t handler)
{
struct irq_desc *desc;
desc = irq_to_desc(irq);
desc->preflow_handler = handler;
}
#endif
#endif #endif
#endif #endif

View File

@ -35,6 +35,9 @@ config AUTO_IRQ_AFFINITY
config HARDIRQS_SW_RESEND config HARDIRQS_SW_RESEND
def_bool n def_bool n
config IRQ_PREFLOW_FASTEOI
def_bool n
config SPARSE_IRQ config SPARSE_IRQ
bool "Support sparse irq numbering" bool "Support sparse irq numbering"
depends on HAVE_SPARSE_IRQ depends on HAVE_SPARSE_IRQ

View File

@ -471,6 +471,16 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
} }
EXPORT_SYMBOL_GPL(handle_level_irq); EXPORT_SYMBOL_GPL(handle_level_irq);
#ifdef CONFIG_IRQ_PREFLOW_FASTEOI
static inline void preflow_handler(struct irq_desc *desc)
{
if (desc->preflow_handler)
desc->preflow_handler(&desc->irq_data);
}
#else
static inline void preflow_handler(struct irq_desc *desc) { }
#endif
/** /**
* handle_fasteoi_irq - irq handler for transparent controllers * handle_fasteoi_irq - irq handler for transparent controllers
* @irq: the interrupt number * @irq: the interrupt number
@ -503,6 +513,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
mask_irq(desc); mask_irq(desc);
goto out; goto out;
} }
preflow_handler(desc);
handle_irq_event(desc); handle_irq_event(desc);
out: out:
desc->irq_data.chip->irq_eoi(&desc->irq_data); desc->irq_data.chip->irq_eoi(&desc->irq_data);