Introduce irq_desc_match_fist_irqaction() to support setup_irq()
code modularity.
Signed-off-by: Ahmed S. Darwish <[email protected]>
---
Any ideas for a better method name ?
manage.c | 89 ++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 51 insertions(+), 38 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 6a0d778..4e96d56 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -293,6 +293,55 @@ int can_add_irqaction_on_allocated_irq(unsigned int irq, struct irqaction *new)
}
/*
+ * Configure the passed irq descriptor to satisfy our first newly
+ * added irqaction needs
+ * must be called with the irq_desc[irq]->lock held
+ */
+void irq_desc_match_fist_irqaction(unsigned int irq, struct irqaction *new)
+{
+ struct irq_desc *desc = irq_desc + irq;
+
+ /* We must be the first and the only irqaction */
+ BUG_ON(desc->action != new || new->next);
+
+ irq_chip_set_defaults(desc->chip);
+
+#if defined(CONFIG_IRQ_PER_CPU)
+ if (new->flags & IRQF_PERCPU)
+ desc->status |= IRQ_PER_CPU;
+#endif
+
+ /* Setup the type (level, edge polarity) if configured: */
+ if (new->flags & IRQF_TRIGGER_MASK) {
+ if (desc->chip && desc->chip->set_type)
+ desc->chip->set_type(irq,
+ new->flags & IRQF_TRIGGER_MASK);
+ else
+ /*
+ * IRQF_TRIGGER_* but the PIC does not support
+ * multiple flow-types?
+ */
+ printk(KERN_WARNING "No IRQF_TRIGGER set_type "
+ "function for IRQ %d (%s)\n", irq,
+ desc->chip ? desc->chip->name : "unknown");
+ } else
+ compat_irq_chip_set_default_handler(desc);
+
+ desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
+
+ if (!(desc->status & IRQ_NOAUTOEN)) {
+ desc->depth = 0;
+ desc->status &= ~IRQ_DISABLED;
+ if (desc->chip->startup)
+ desc->chip->startup(irq);
+ else
+ desc->chip->enable(irq);
+ } else
+ /* Undo nested disables: */
+ desc->depth = 1;
+}
+
+/*
* Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
*/
@@ -352,45 +401,9 @@ int setup_irq(unsigned int irq, struct irqaction *new)
if (new->flags & IRQF_NOBALANCING)
desc->status |= IRQ_NO_BALANCING;
- if (!shared) {
- irq_chip_set_defaults(desc->chip);
+ if (!shared)
+ irq_desc_match_fist_irqaction(irq, new);
-#if defined(CONFIG_IRQ_PER_CPU)
- if (new->flags & IRQF_PERCPU)
- desc->status |= IRQ_PER_CPU;
-#endif
-
- /* Setup the type (level, edge polarity) if configured: */
- if (new->flags & IRQF_TRIGGER_MASK) {
- if (desc->chip && desc->chip->set_type)
- desc->chip->set_type(irq,
- new->flags & IRQF_TRIGGER_MASK);
- else
- /*
- * IRQF_TRIGGER_* but the PIC does not support
- * multiple flow-types?
- */
- printk(KERN_WARNING "No IRQF_TRIGGER set_type "
- "function for IRQ %d (%s)\n", irq,
- desc->chip ? desc->chip->name :
- "unknown");
- } else
- compat_irq_chip_set_default_handler(desc);
-
- desc->status &= ~(IRQ_AUTODETECT | IRQ_WAITING |
- IRQ_INPROGRESS);
-
- if (!(desc->status & IRQ_NOAUTOEN)) {
- desc->depth = 0;
- desc->status &= ~IRQ_DISABLED;
- if (desc->chip->startup)
- desc->chip->startup(irq);
- else
- desc->chip->enable(irq);
- } else
- /* Undo nested disables: */
- desc->depth = 1;
- }
/* Reset broken irq detection when installing new handler */
desc->irq_count = 0;
desc->irqs_unhandled = 0;
--
Ahmed S. Darwish
HomePage: http://darwish.07.googlepages.com
Blog: http://darwish-07.blogspot.com
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]