diff options
-rw-r--r-- | include/linux/irq.h | 9 | ||||
-rw-r--r-- | kernel/irq/chip.c | 56 |
2 files changed, 64 insertions, 1 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index a31a7d8acdb..82dbb0e8f40 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -404,8 +404,15 @@ set_irq_chained_handler(unsigned int irq, __set_irq_handler(irq, handle, 1); } -/* Set/get chip/data for an IRQ: */ +/* Handle dynamic irq creation and destruction */ +extern int create_irq(void); +extern void destroy_irq(unsigned int irq); + +/* Dynamic irq helper functions */ +extern void dynamic_irq_init(unsigned int irq); +extern void dynamic_irq_cleanup(unsigned int irq); +/* Set/get chip/data for an IRQ: */ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); extern int set_irq_data(unsigned int irq, void *data); extern int set_irq_chip_data(unsigned int irq, void *data); diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 736cb0bd498..0dc24386dd9 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -18,6 +18,62 @@ #include "internals.h" /** + * dynamic_irq_init - initialize a dynamically allocated irq + * @irq: irq number to initialize + */ +void dynamic_irq_init(unsigned int irq) +{ + struct irq_desc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); + WARN_ON(1); + return; + } + + /* Ensure we don't have left over values from a previous use of this irq */ + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock, flags); + desc->status = IRQ_DISABLED; + desc->chip = &no_irq_chip; + desc->handle_irq = handle_bad_irq; + desc->depth = 1; + desc->handler_data = NULL; + desc->chip_data = NULL; + desc->action = NULL; + desc->irq_count = 0; + desc->irqs_unhandled = 0; +#ifdef CONFIG_SMP + desc->affinity = CPU_MASK_ALL; +#endif + spin_unlock_irqrestore(&desc->lock, flags); +} + +/** + * dynamic_irq_cleanup - cleanup a dynamically allocated irq + * @irq: irq number to initialize + */ +void dynamic_irq_cleanup(unsigned int irq) +{ + struct irq_desc *desc; + unsigned long flags; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); + WARN_ON(1); + return; + } + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock, flags); + desc->handle_irq = handle_bad_irq; + desc->chip = &no_irq_chip; + spin_unlock_irqrestore(&desc->lock, flags); +} + + +/** * set_irq_chip - set the irq chip for an irq * @irq: irq number * @chip: pointer to irq chip description structure |