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 a31a7d8acdb2..82dbb0e8f40b 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -404,8 +404,15 @@ set_irq_chained_handler(unsigned int irq, | |||
404 | __set_irq_handler(irq, handle, 1); | 404 | __set_irq_handler(irq, handle, 1); |
405 | } | 405 | } |
406 | 406 | ||
407 | /* Set/get chip/data for an IRQ: */ | 407 | /* Handle dynamic irq creation and destruction */ |
408 | extern int create_irq(void); | ||
409 | extern void destroy_irq(unsigned int irq); | ||
410 | |||
411 | /* Dynamic irq helper functions */ | ||
412 | extern void dynamic_irq_init(unsigned int irq); | ||
413 | extern void dynamic_irq_cleanup(unsigned int irq); | ||
408 | 414 | ||
415 | /* Set/get chip/data for an IRQ: */ | ||
409 | extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); | 416 | extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); |
410 | extern int set_irq_data(unsigned int irq, void *data); | 417 | extern int set_irq_data(unsigned int irq, void *data); |
411 | extern int set_irq_chip_data(unsigned int irq, void *data); | 418 | extern int set_irq_chip_data(unsigned int irq, void *data); |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 736cb0bd498f..0dc24386dd99 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -18,6 +18,62 @@ | |||
18 | #include "internals.h" | 18 | #include "internals.h" |
19 | 19 | ||
20 | /** | 20 | /** |
21 | * dynamic_irq_init - initialize a dynamically allocated irq | ||
22 | * @irq: irq number to initialize | ||
23 | */ | ||
24 | void dynamic_irq_init(unsigned int irq) | ||
25 | { | ||
26 | struct irq_desc *desc; | ||
27 | unsigned long flags; | ||
28 | |||
29 | if (irq >= NR_IRQS) { | ||
30 | printk(KERN_ERR "Trying to initialize invalid IRQ%d\n", irq); | ||
31 | WARN_ON(1); | ||
32 | return; | ||
33 | } | ||
34 | |||
35 | /* Ensure we don't have left over values from a previous use of this irq */ | ||
36 | desc = irq_desc + irq; | ||
37 | spin_lock_irqsave(&desc->lock, flags); | ||
38 | desc->status = IRQ_DISABLED; | ||
39 | desc->chip = &no_irq_chip; | ||
40 | desc->handle_irq = handle_bad_irq; | ||
41 | desc->depth = 1; | ||
42 | desc->handler_data = NULL; | ||
43 | desc->chip_data = NULL; | ||
44 | desc->action = NULL; | ||
45 | desc->irq_count = 0; | ||
46 | desc->irqs_unhandled = 0; | ||
47 | #ifdef CONFIG_SMP | ||
48 | desc->affinity = CPU_MASK_ALL; | ||
49 | #endif | ||
50 | spin_unlock_irqrestore(&desc->lock, flags); | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * dynamic_irq_cleanup - cleanup a dynamically allocated irq | ||
55 | * @irq: irq number to initialize | ||
56 | */ | ||
57 | void dynamic_irq_cleanup(unsigned int irq) | ||
58 | { | ||
59 | struct irq_desc *desc; | ||
60 | unsigned long flags; | ||
61 | |||
62 | if (irq >= NR_IRQS) { | ||
63 | printk(KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq); | ||
64 | WARN_ON(1); | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | desc = irq_desc + irq; | ||
69 | spin_lock_irqsave(&desc->lock, flags); | ||
70 | desc->handle_irq = handle_bad_irq; | ||
71 | desc->chip = &no_irq_chip; | ||
72 | spin_unlock_irqrestore(&desc->lock, flags); | ||
73 | } | ||
74 | |||
75 | |||
76 | /** | ||
21 | * set_irq_chip - set the irq chip for an irq | 77 | * set_irq_chip - set the irq chip for an irq |
22 | * @irq: irq number | 78 | * @irq: irq number |
23 | * @chip: pointer to irq chip description structure | 79 | * @chip: pointer to irq chip description structure |