From 7dd471f66a5b1eafd301252d1b826ac12ba51c0b Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 4 Oct 2006 02:16:37 -0700 Subject: [PATCH] --- yaml --- r: 38419 b: refs/heads/master c: 3a16d713626735f3016da0521b7bf251cd78e836 h: refs/heads/master i: 38417: e18a1f7bb659964238be458d681e22852f2a87af 38415: 57d88bbe3220f5dd85edaa7a15e32705eed4d1bb v: v3 --- [refs] | 2 +- trunk/include/linux/irq.h | 9 ++++++- trunk/kernel/irq/chip.c | 56 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index f3bcadd390cf..d63688b230a3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 92db6d10bc1bc43330a4c540fa5b64c83d9d865f +refs/heads/master: 3a16d713626735f3016da0521b7bf251cd78e836 diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index a31a7d8acdb2..82dbb0e8f40b 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/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/trunk/kernel/irq/chip.c b/trunk/kernel/irq/chip.c index 736cb0bd498f..0dc24386dd99 100644 --- a/trunk/kernel/irq/chip.c +++ b/trunk/kernel/irq/chip.c @@ -17,6 +17,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