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/

Reply via email to