From 02cc1b658d7a37ba9a0069fef837c6bc2e29f881 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 10 Feb 2011 15:14:20 +0100 Subject: [PATCH] --- yaml --- r: 234759 b: refs/heads/master c: 781295762defc709a609efc01d8bb065276cd9a2 h: refs/heads/master i: 234757: afe68e3767a894efa8909d7979529621403e5b9c 234755: 6feb3598206c221143992aa11dbee8ac9181367c 234751: 5f788bbcd8f6dca841e323c0b34ed9a8663678c3 v: v3 --- [refs] | 2 +- trunk/include/linux/irq.h | 3 ++- trunk/include/linux/irqdesc.h | 14 ++++++++++++++ trunk/kernel/irq/Kconfig | 3 +++ trunk/kernel/irq/chip.c | 11 +++++++++++ 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 6a55e650d2d6..fa9ddb6f2bd9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3836ca08aad4575c120ccf328652f3873eea9063 +refs/heads/master: 781295762defc709a609efc01d8bb065276cd9a2 diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index 3e29e2f42e04..36390970693c 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -29,9 +29,10 @@ #include struct irq_desc; +struct irq_data; typedef void (*irq_flow_handler_t)(unsigned int irq, struct irq_desc *desc); - +typedef void (*irq_preflow_handler_t)(struct irq_data *data); /* * IRQ line status. diff --git a/trunk/include/linux/irqdesc.h b/trunk/include/linux/irqdesc.h index 36c95f08023d..2f87d6441302 100644 --- a/trunk/include/linux/irqdesc.h +++ b/trunk/include/linux/irqdesc.h @@ -63,6 +63,9 @@ struct irq_desc { struct timer_rand_state *timer_rand_state; unsigned int __percpu *kstat_irqs; irq_flow_handler_t handle_irq; +#ifdef CONFIG_IRQ_PREFLOW_FASTEOI + irq_preflow_handler_t preflow_handler; +#endif struct irqaction *action; /* IRQ action list */ #ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT unsigned int status_use_accessors; @@ -187,6 +190,17 @@ static inline void __set_irq_handler_unlocked(int irq, desc = irq_to_desc(irq); 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 diff --git a/trunk/kernel/irq/Kconfig b/trunk/kernel/irq/Kconfig index 48ad25f5fa59..9149be729e45 100644 --- a/trunk/kernel/irq/Kconfig +++ b/trunk/kernel/irq/Kconfig @@ -35,6 +35,9 @@ config AUTO_IRQ_AFFINITY config HARDIRQS_SW_RESEND def_bool n +config IRQ_PREFLOW_FASTEOI + def_bool n + config SPARSE_IRQ bool "Support sparse irq numbering" depends on HAVE_SPARSE_IRQ diff --git a/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 2a36038b8f59..08be5d182be3 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -471,6 +471,16 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc) } 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 * @irq: the interrupt number @@ -503,6 +513,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc) mask_irq(desc); goto out; } + preflow_handler(desc); handle_irq_event(desc); out: desc->irq_data.chip->irq_eoi(&desc->irq_data);