Messages in this thread Patch in this message | | | From | Torben Hohn <> | Subject | [PATCH 4/5] RFC genirq: allow dynamic switching of timestamping irqs | Date | Mon, 21 Mar 2011 12:59:19 +0100 |
| |
Subsystems might want to dynamically switch irq timestamping, if some subsystem driver requests timestamps.
This patch adds: void irq_turn_on_timestamping(unsigned int irq, void *dev_id) void irq_turn_off_timestamping(unsigned int irq, void *dev_id)
Signed-off-by: Torben Hohn <torbenh@gmx.de> --- include/linux/interrupt.h | 3 ++ kernel/irq/manage.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 906b3b6..cc9ed9c 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -175,6 +175,9 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler, static inline void exit_irq_thread(void) { } #endif +extern void irq_turn_on_timestamping(unsigned int irq, void *dev_id); +extern void irq_turn_off_timestamping(unsigned int irq, void *dev_id); + extern void free_irq(unsigned int, void *); struct device; diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index b60350f..66e9501 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -649,6 +649,72 @@ void exit_irq_thread(void) } /* + * irq_turn_on_timestamping - Turn on timestamping for irq line. + * @irq: Interrupt line + * @dev_id: Device Id for which to turn on timestamping. + * (must point to a struct timespec) + * + * Turning on timestamping nests. + */ +void irq_turn_on_timestamping(unsigned int irq, void *dev_id) +{ + struct irq_desc *desc = irq_to_desc(irq); + unsigned long flags; + struct irqaction *act; + + raw_spin_lock_irqsave(&desc->lock, flags); + desc->status |= IRQ_TIMESTAMP; + + act = desc->action; + while (act) { + if (act->dev_id == dev_id) { + act->flags |= IRQF_TIMESTAMP; + break; + } + act = act->next; + } + + BUG_ON( act==NULL ); + + raw_spin_unlock_irqrestore(&desc->lock, flags); + + /* maybe we need to synchronise_irq() here ??? */ +} +EXPORT_SYMBOL_GPL(irq_turn_on_timestamping); + +/* + * irq_turn_off_timestamping - Turn off timestamping for irq line. + * @irq: Interrupt line + * @dev_id: Device Id for which to turn off timestamping. + * + * Turning on timestamping nests. + */ +void irq_turn_off_timestamping(unsigned int irq, void *dev_id) +{ + struct irq_desc *desc = irq_to_desc(irq); + unsigned long flags; + struct irqaction *act; + unsigned long irqf_accu = 0; + + raw_spin_lock_irqsave(&desc->lock, flags); + + act = desc->action; + while (act) { + if (act->dev_id == dev_id) { + act->flags &= ~(IRQF_TIMESTAMP); + } + irqf_accu |= act->flags; + act = act->next; + } + + if ((irqf_accu & IRQF_TIMESTAMP) == 0) + desc->status &= ~(IRQ_TIMESTAMP); + + raw_spin_unlock_irqrestore(&desc->lock, flags); +} +EXPORT_SYMBOL_GPL(irq_turn_off_timestamping); + +/* * Internal function to register an irqaction - typically used to * allocate special interrupts that are part of the architecture. */ -- 1.7.2.3
| |