Hi Thomas/lkml,

setup_irq() code contains a big chunk of 130 code lines that 
can be divided to several smaller methods. These 2 patches introduce 
those small functions to aid toward setup_irq() code modularity. 
No major code logic changes exist.

Patches can be applied cleanly over v2.6.23-rc9.

Thanks,

==> (Description for Logs)

Introduce can_add_irqaction_on_allocated_irq and warn_about_irqaction_mismatch
methods to support setup_irq() code modularity.

Signed-off-by: Ahmed S. Darwish <[EMAIL PROTECTED]>
---

 manage.c |   92 +++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 7230d91..6a0d778 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -248,6 +248,50 @@ void compat_irq_chip_set_default_handler(struct irq_desc 
*desc)
                desc->handle_irq = NULL;
 }
 
+static inline void warn_about_irqaction_mismatch(unsigned int irq,
+                                                struct irqaction *new)
+{
+#ifdef CONFIG_DEBUG_SHIRQ
+       const char *name = irq_desc[irq].action->name;
+       /* If device doesn't expect the mismatch */
+       if (!(new->flags & IRQF_PROBE_SHARED)) {
+               printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
+               if (name)
+                       printk(KERN_ERR "current handler: %s\n", name);
+               dump_stack();
+       }
+#endif
+}
+
+/*
+ * Test if an irqaction can be added to the passed allocated IRQ line
+ * Must be called with the irq_desc[irq]->lock held.
+ */
+int can_add_irqaction_on_allocated_irq(unsigned int irq, struct irqaction *new)
+{
+       struct irqaction *old = irq_desc[irq].action;
+
+       BUG_ON(!old);
+       /*
+        * Can't share interrupts unless both agree to and are
+        * the same type (level, edge, polarity). So both flag
+        * fields must have IRQF_SHARED set and the bits which
+        * set the trigger type must match.
+        */
+       if (!((old->flags & new->flags) & IRQF_SHARED) ||
+           ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))
+               return 0;
+
+#if defined(CONFIG_IRQ_PER_CPU)
+       /* All handlers must agree on per-cpuness */
+       if ((old->flags & IRQF_PERCPU) !=
+           (new->flags & IRQF_PERCPU))
+               return 0;
+#endif
+
+       return 1;
+}
+
 /*
  * Internal function to register an irqaction - typically used to
  * allocate special interrupts that are part of the architecture.
@@ -256,7 +300,6 @@ int setup_irq(unsigned int irq, struct irqaction *new)
 {
        struct irq_desc *desc = irq_desc + irq;
        struct irqaction *old, **p;
-       const char *old_name = NULL;
        unsigned long flags;
        int shared = 0;
 
@@ -289,31 +332,18 @@ int setup_irq(unsigned int irq, struct irqaction *new)
        p = &desc->action;
        old = *p;
        if (old) {
-               /*
-                * Can't share interrupts unless both agree to and are
-                * the same type (level, edge, polarity). So both flag
-                * fields must have IRQF_SHARED set and the bits which
-                * set the trigger type must match.
-                */
-               if (!((old->flags & new->flags) & IRQF_SHARED) ||
-                   ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK)) {
-                       old_name = old->name;
-                       goto mismatch;
-               }
-
-#if defined(CONFIG_IRQ_PER_CPU)
-               /* All handlers must agree on per-cpuness */
-               if ((old->flags & IRQF_PERCPU) !=
-                   (new->flags & IRQF_PERCPU))
-                       goto mismatch;
-#endif
-
-               /* add new interrupt at end of irq queue */
-               do {
-                       p = &old->next;
-                       old = *p;
-               } while (old);
                shared = 1;
+               if (can_add_irqaction_on_allocated_irq(irq, new)) {
+                       /* add new interrupt at end of irq queue */
+                       do {
+                               p = &old->next;
+                               old = *p;
+                       } while (old);
+               } else {
+                       warn_about_irqaction_mismatch(irq, new);
+                       spin_unlock_irqrestore(&desc->lock, flags);
+                       return -EBUSY;
+               }
        }
 
        *p = new;
@@ -372,18 +402,6 @@ int setup_irq(unsigned int irq, struct irqaction *new)
        register_handler_proc(irq, new);
 
        return 0;
-
-mismatch:
-#ifdef CONFIG_DEBUG_SHIRQ
-       if (!(new->flags & IRQF_PROBE_SHARED)) {
-               printk(KERN_ERR "IRQ handler type mismatch for IRQ %d\n", irq);
-               if (old_name)
-                       printk(KERN_ERR "current handler: %s\n", old_name);
-               dump_stack();
-       }
-#endif
-       spin_unlock_irqrestore(&desc->lock, flags);
-       return -EBUSY;
 }
 
 /**


-- 
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